【问题标题】:MvvmLight, Messenger, and Async method callsMvvmLight、Messenger 和 Async 方法调用
【发布时间】:2014-01-25 02:56:13
【问题描述】:

我正在使用 MvvmLight 并使用 MessengerInstance.Send(...) 方法实现了我的一些 ViewModel 之间的通信。效果很好!

不过,最近,我已经从使用同步方法转移到异步方法来检索数据,看起来这会破坏消息传递(可能是因为它在不同的线程上执行)。例如:

public ICommand SomeCommand { get { return new RelayCommand(DoSomething); } }

private async void DoSomething(object obj)
{
    //Used to be SomeWcfService.DoSomething(); with some logic afterward
    await SomeWcfService.DoSomethingAsync().ContinueWith(task => { //Some logic after method completes });

    MessengerInstance.Send(SomeDataToSend, MessageIdentifer.DoSomething);
}

【问题讨论】:

    标签: c# wpf mvvm task-parallel-library mvvm-light


    【解决方案1】:

    不要使用延续,而是放在await之后:

    private async void DoSomething(object obj)
    {
        //Used to be SomeWcfService.DoSomething(); with some logic afterward
        var result = await SomeWcfService.DoSomethingAsync();
    
        // .ContinueWith(task => { //Some logic after method completes });
        // use result here!
    
        MessengerInstance.Send(SomeDataToSend, MessageIdentifer.DoSomething);
    }
    

    如果DoSomethingAsync 没有返回结果,您可以省略结果,然后将代码放在适当的位置。

    正如您所写的,延续不会在相同的同步上下文中运行。 await 关键字实际上是在异步等待您的继续,而不是来自 WCF 的异步方法。

    如果您的“某些逻辑”是异步的,您也可以在该代码中使用 await

    【讨论】:

    • 我在想 MessengerInstance.Send() 没有在同一个线程中运行,因为 DoSomething(类方法,而不是 WCF)在单独的线程上运行。这让我认为这就是为什么我的单元测试没有看到消息弹出的原因。我不知道是不是这样,但按照你的建议(不使用延续)做的很好!谢谢!
    • async void?这不应该是async Task 吗?
    • @PanagiotisKanavos 通常,它必须是 void 方法才能在大多数命令实现中使用。我有一个可以使用async Task,但大多数需要async void(*不幸的是)`
    猜你喜欢
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多