CommunityToolkit / CommunityToolkit/dotnet

IMessenger.Send behaviour

Open
#1,042 1 comment 0 reactions 0 assignees View on GitHub
bug :bug:
Dominant language
C#
Stars
3.8k
Forks
400
PR merge metrics
No merged PRs in 30d

Description

### Describe the bug

**Service registration:**
`AddSingleton(WeakReferenceMessenger.Default)`

**Message registration:**
`_messenger.Register(this, static (r, m) => m.Reply(r.Action1(m)));`

**Behavour:**

_Case1:_
If `Action1` is of type `Task` and we do following:
```csharp
string response = await _messenger.Send(new());

private async Task Action1(TestAsyncMessage1 msg)
{
await Task.Delay(TimeSpan.FromSeconds(5));
Trace.WriteLine("Action1 process complete");
return "hello";
}
```
the response is of type `string` and contains the value `hello`.

_Case2:_
However, if `Action1` is of type `Task` and we do following:
```csharp
Task response = await _messenger.Send(new());

private async Task Action1(TestAsyncMessage1 msg)
{
await Task.Delay(TimeSpan.FromSeconds(5));
Trace.WriteLine("Action1 process complete");
}
```
the response is of type `Task`.

**Issue:**
In _Case1_ does the `await` actually awaits the internal task (Action1) and return the value of the task, in this case the string `hello`.
In _Case2_ does the `await` awaits that the message is sent, but not the internal task (Action1).

So if we want the same behaviour for _Case2_, where we want the internal task to be completed, we have to do something like:
```csharp
Task response = await _messenger.Send(new());
await response;
```

We are now implementation our own solution, using an extension method:
```csharp
public static class ExtensionMethods
{
public static async Task ProcessTask(this IMessenger messenger, TMessage message)
where TMessage : AsyncRequestMessage
{
var task = await messenger.Send(message);
await task;
}

public static Task ProcessTask(this IMessenger messenger)
where TMessage : AsyncRequestMessage, new()
=> messenger.ProcessTask(new TMessage());
}
```

Making it possible to do following:
```csharp
await _messenger.ProcessTask(new());
```

**Description**
Depening on the return type, we have different behavour.
Is this wanted? Would it make sense to add something like `ProcessTask` to the library to extend the functionality?

### Regression

_No response_

### Steps to reproduce

Microsoft Visual Studio Professional 2022 (64-bit) - Current
Version 17.12.4

CommunityToolkit.Mvvm
Version 8.2.2

### Expected behavior

See description of bug.

### Screenshots

_No response_

### IDE and version

VS 2022

### IDE version

Version 17.12.4

### Nuget packages

- [ ] CommunityToolkit.Common
- [ ] CommunityToolkit.Diagnostics
- [ ] CommunityToolkit.HighPerformance
- [x] CommunityToolkit.Mvvm (aka MVVM Toolkit)

### Nuget package version(s)

8.2.2

### Additional context

_No response_

### Help us help you

Yes, I'd like to be assigned to work on this item

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.