Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMessenger.Send behaviour #1042

Open
1 of 4 tasks
viktor-morin opened this issue Jan 17, 2025 · 1 comment
Open
1 of 4 tasks

IMessenger.Send behaviour #1042

viktor-morin opened this issue Jan 17, 2025 · 1 comment
Labels
bug 🐛 An unexpected issue that highlights incorrect behavior

Comments

@viktor-morin
Copy link

Describe the bug

Service registration:
AddSingleton<IMessenger>(WeakReferenceMessenger.Default)

Message registration:
_messenger.Register<AsyncRelayCommandPageViewModel, TestAsyncMessage1>(this, static (r, m) => m.Reply(r.Action1(m)));

Behavour:

Case1:
If Action1 is of type Task<T> and we do following:

string response = await _messenger.Send<TestAsyncMessage1>(new());

private async Task<string> 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:

Task response = await _messenger.Send<TestAsyncMessage1>(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:

Task response = await _messenger.Send<TestAsyncMessage1>(new());
await response;

We are now implementation our own solution, using an extension method:

public static class ExtensionMethods
{
    public static async Task ProcessTask<TMessage>(this IMessenger messenger, TMessage message)
        where TMessage : AsyncRequestMessage<Task>
        {
            var task = await messenger.Send(message);
            await task;
        }

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

Making it possible to do following:

await _messenger.ProcessTask<TestAsyncMessage1>(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
  • 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

@viktor-morin viktor-morin added the bug 🐛 An unexpected issue that highlights incorrect behavior label Jan 17, 2025
@viktor-morin viktor-morin changed the title IMessenger.Send behavour IMessenger.Send behaviour Jan 17, 2025
@viktor-morin
Copy link
Author

After more investigation, we have decided that we are using async messages the wrong way.
However, we still belive that the difference in behavior when a Task vs Task<string> are the return type should be investigated or clarified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 An unexpected issue that highlights incorrect behavior
Projects
None yet
Development

No branches or pull requests

1 participant