lbugnion / mvvmlight

The main purpose of the toolkit is to accelerate the creation and development of MVVM applications in Xamarin.Android, Xamarin.iOS, Xamarin.Forms, Windows 10 UWP, Windows Presentation Foundation (WPF), Silverlight, Windows Phone.
http://www.mvvmlight.net
MIT License
1.17k stars 311 forks source link

Async Messenger #16

Open fharr opened 6 years ago

fharr commented 6 years ago

It would be great if it was possible to await a Messenger.Send method when the registered method is async.

For example:

class Caller : ViewModelBase
{
    async Task CallingMethod()
    {
        // Do things

        await this.MessengerInstance.SendAsync(new Message());

        // Do other things
    }
}

class Receiver : ViewModelBase
{
    Receiver()
    {
        this.MessengerInstance.RegisterAsync<Message>(this, OnMessageAsync);
    }

    private async Task OnMessageAsync(Navigation msg)
    {
        await AsyncThingsOnReceive();
    }
}

I don't even know if this is possible regarding to your architecture. This guy made an attempt to solve this issue but I think it is not compatible with the last version of MVVM Light : https://github.com/runceel/AsyncMessenger.

gs-ts commented 6 years ago

just out of curiosity, why would you need that? Any practical example?

fharr commented 6 years ago

I am not sure my practical example is relevant here, since I do not have anything particular in it except the use of an awaitable registered method (async void OnMessageAsync(Message obj)). I guess this case is pretty frequent with the async/await feature.

In my case, when the the execution hit the await keyword in the registered OnMessageAsync method, the execution stops and resumes on the CallingMethod. When the CallingMethod is finished, the execution resumes on the registered OnMessageAsync and finish its execution.

Because of that, every instructions written after the call to the Send method is not ensured to be executed after the registered method.

OmiCron07 commented 6 years ago

I have the exact same problem. Before, the send was blocking the execution until the end of the message method. When I put async to the message method to be able to await async methods, the send resume at the first await in the message method and all the logic is screw.

smeddows commented 5 years ago

I could see where you could need this if you're using messages to open different windows and you don't want to block from the VM that you are sending the message from. Especially i the dialog that you call isn't modal, or, it needs to be modal but you still want to pump messages from the previous window.

Eagle3386 commented 4 years ago

I am not sure my practical example is relevant here, since I do not have anything particular in it except the use of an awaitable registered method (async void OnMessageAsync(Message obj)). I guess this case is pretty frequent with the async/await feature. (...)

This should've already warned you that you're doing something completely wrong.

Never, never, never, never, never ever use async void anywhere in your code!

Read here for why: https://johnthiriet.com/removing-async-void/