Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WinRT跨线程同步异步调用_C#_Multithreading_Asynchronous_Lambda_Windows Runtime - Fatal编程技术网

C# WinRT跨线程同步异步调用

C# WinRT跨线程同步异步调用,c#,multithreading,asynchronous,lambda,windows-runtime,C#,Multithreading,Asynchronous,Lambda,Windows Runtime,我对WinRT项目有意见。当前程序的执行在两个线程上运行。一个线程执行主应用程序,另一个线程处理UI方面的事情。目前,我遇到一个问题,从主线程调用函数在UI线程上执行,等待回复,然后继续在主线程上执行。。。让我向您展示一些代码作为示例 public async void SignOut(Action onSuccess, Action onFailure) { bool success = false; bool wait = true; CoreApplication

我对WinRT项目有意见。当前程序的执行在两个线程上运行。一个线程执行主应用程序,另一个线程处理UI方面的事情。目前,我遇到一个问题,从主线程调用函数在UI线程上执行,等待回复,然后继续在主线程上执行。。。让我向您展示一些代码作为示例

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的wait SignOutAsync()部分,RunAsync任务就会将自己标记为完成,并在SignOutAsync方法产生任何结果之前返回成功/失败检查。我相信这是由于嵌套的异步方法造成的,您不能等待RunAsync调用,然后再等待其中的异步lambda

如有任何建议,将不胜感激

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

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

目前,我在从主线程调用函数以在UI线程上执行时遇到了一个问题,等待响应,然后继续在主线程上执行

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

也就是说,如果您绝对必须有一个“特殊”的背景线程,那么可以使用
AsyncContextThread
理解异步方法,因此您可以执行以下操作:

public async Task SignOutAsync(Action onSuccess, Action onFailure)
{
    try
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => SignOutAsync());
        onSuccess();
    }
    catch
    {
        onFailure();
    }
}
然而,如果将此代码投入生产,我会感到尴尬;任何使用
Dispatcher
的东西都是一种代码气味。尽管我编写了
AsyncContextThread
类型,但我不能将其推荐给Windows应用商店项目。一个更好的设计是对代码进行结构化,这样程序逻辑就不会回调到UI中