WinRT跨线程同步异步调用

时间:2013-12-16 14:24:36

标签: c# multithreading asynchronous lambda windows-runtime

我遇到了WinRT项目的问题。目前,程序上的执行是在两个线程上运行的。一个线程执行主应用程序,另一个线程处理事物的UI方面。目前,我遇到一个问题,从主线程调用一个函数在UI线程上执行,等待回复,然后继续在主线程上执行......让我给你看一些代码作为例子。 / p>

public async void SignOut(Action onSuccess, Action onFailure)
{
    bool success = false;
    bool wait = true;

    CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
    {
        await SignOutAsync();
        success = true;
        wait = false;
    });

    while (wait) { }

    if (success)
    {
        onSuccess();
    }
    else
    {
        onFailure();
    }
}

所以这段代码正在做我想要它做的事情,但显然不是正确的方式去忙着等待所有这一切。问题是,如果我将OnSuccess / OnFailure执行移动到RunAsync lambda中,那么关于无效内存的回调就会出错,因为执行是在不同的线程上。目前我遇到的问题是我无法在不搞砸执行顺序的情况下删除繁忙的等待。理想情况下,我想等待整个RunAsync lambda在UI线程上完成执行,然后返回主线程来运行成功/失败回调。

目前看来,只要我点击RunAsync lambda的SignOutAsync()部分,RunAsync任务就会将自己标记为完成,并在SignOutAsync方法有任何结果之前返回成功/失败检查。我相信这是由于嵌套的异步方法,你无法真正等待RunAsync调用,然后再次在其中的异步lambda上。

非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

  

目前程序上的执行是在两个线程上运行的。一个线程执行主应用程序,另一个线程处理UI方面。

这不太理想。如果可能的话,构造你的代码,这样你只有一个“特殊”线程(UI线程)。 async允许您的UI线程保持响应,而无需第二个“特殊”线程。

  

目前,我遇到一个问题,即从主线程调用一个函数在UI线程上执行,等待回复,然后继续在主线程上执行。

同样,更好的设计是让您的程序逻辑为UI提供“服务”,而不是相反。因此,尽力重新设计调用,以便UI驱动程序逻辑,而不是相反。

也就是说,如果你绝对必须拥有一个“特殊”后台主题,你可以使用AsyncContextThread type from my AsyncEx libraryAsyncContextThread了解异步方法,因此您可以这样做:

public async Task SignOutAsync(Action onSuccess, Action onFailure)
{
    try
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => SignOutAsync());
        onSuccess();
    }
    catch
    {
        onFailure();
    }
}

但是,我很尴尬地将这些代码投入生产;使用Dispatcher的任何东西都是代码气味。即使我写了AsyncContextThread类型,我也不推荐它用于Windows Store项目。更好的设计是构造代码,以便程序逻辑永远不会回调到UI。