简体   繁体   English

对调度程序和异步感到困惑

[英]Confused about dispatcher and async

I'm making a windows 8.1 tablet app and am using the async keyword quite heavily. 我正在制作一个Windows 8.1平板电脑应用程序并且非常使用async关键字。 My understanding of the async keyword is that, while it appears to be synchronous to the programmer, there is no guarantee that you will be running on the same thread when your await finishes. 我对async关键字的理解是,虽然它似乎与程序员同步,但是当你的await完成时,不能保证你将在同一个线程上运行。

In my code behind file I have the use of the Dispatcher to run any UI updates on the UI thread. 在我的代码隐藏文件中,我使用Dispatcher在UI线程上运行任何UI更新。 Every example I've found indicates this to be good practice when using a 'callback' type scenario but I've seen no mention of it when using async. 我发现的每个例子都表明在使用'回调'类型场景时这是一个很好的做法但我在使用异步时没有看到它。 From my understanding of async, it would appear as though I'd need to use the dispatcher whenever I want to update the UI after any await call. 根据我对async的理解,似乎每当我想在任何await调用之后更新UI时,我都需要使用调度程序。

I've tried to be clearer by putting my understanding in code below. 通过在下面的代码中理解我,我试图更清楚。

private void SomeEventHandler(object sender, RoutedEventArgs e)
{
    UpdateUI(); //This should run in my UI thread
    await Foo(); //When Foo returns I have no guarantee that I am in the same thread
    UpdateUI(); //This could potentially give me an error
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        UpdateUI(); //This will run in the UI thread
    });
}

Do I just need access to the UIContext and the thread doesn't matter? 我只需要访问UIContext并且线程无关紧要吗? It would be great if someone could clarify this for me. 如果有人能为我澄清这一点会很棒。

My understanding of the async keyword is that, while it appears to be synchronous to the programmer, there is no guarantee that you will be running on the same thread when your await finishes. 我对async关键字的理解是,虽然它似乎与程序员同步,但是当你的await完成时,不能保证你将在同一个线程上运行。

Not exactly... If the thread that starts the async operation has a synchronization context (which is true for the UI thread), execution will always resume on the same thread, unless you explicitly specified not to capture the synchronization context with .ConfigureAwait(false) . 不完全......如果启动异步操作的线程具有同步上下文(对于UI线程都是如此),则执行将始终在同一线程上继续执行,除非您明确指定不使用.ConfigureAwait(false)捕获同步上下文.ConfigureAwait(false)

If there is no synchronization context, or if it wasn't captured, then execution will resume on a ThreadPool thread (except if the awaited task actually completes synchronously, in which case you stay on the same thread). 如果没有同步上下文,或者没有捕获,则执行将在ThreadPool线程上恢复(除非等待的任务实际上同步完成,在这种情况下,您将保持在同一个线程上)。

So, here's your code snippet with updated comments: 那么,这是您的代码片段,其中包含更新的评论:

private void SomeEventHandler(object sender, RoutedEventArgs e)
{
    UpdateUI(); //This should run in my UI thread
    await Foo(); //When Foo returns I am still in the UI thread
    UpdateUI(); //This will work fine, as I'm still in the UI thread

    // This is useless, since I'm already in the UI thread ;-)
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        UpdateUI(); //This will run in the UI thread
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM