0

更新现在不是问题。没有意识到 Dispatcher.Invoke 方法内外返回的 theadID 是不同的。

据我了解,当使用异步时,等待任务 T1 将在不同的线程中执行,等待之后的代码被包装为任务 T2,其 ContinueWith 为 T1。所以我假设 threadcontextID 在下面的代码中会有所不同。但是下面的代码生成相同的 ThreadContextID。我的理解错了吗?

另外,为什么我必须在 T1 中使用 Dispatcher,但可以直接在 T2 中更新主 UI?threadContext 开关在 async/await 中如何工作?谢谢。

更新: T1 中的代码正在 VS 调试线程视图的 MainThread 中执行。但是,如果是在主线程中,为什么我不能直接更新 UI?它给了我 CrossThread 异常。

async private void AsyncTask(object sender, RoutedEventArgs e)
    {
        OutputDialog.Text = Thread.CurrentThread.ManagedThreadId+ Environment.NewLine + OutputDialog.Text;

        Task T1 = new Task(
                    () => {
                            Thread.Sleep(5000);
                            OutputDialog.Dispatcher.Invoke(() => { 
                                OutputDialog.Text = "Task in AWAIT" + Environment.NewLine + OutputDialog.Text;
                                OutputDialog.Text = Thread.CurrentThread.ManagedThreadId + Environment.NewLine + OutputDialog.Text;
                            });
                    });

        T1.Start();

        await T1;

        //T2
        OutputDialog.Dispatcher.Invoke(() => { OutputDialog.Text = "Continued Task after AWAIT 1" + Environment.NewLine + OutputDialog.Text; });

        OutputDialog.Text = "Continued Task after AWAIT 2" + Environment.NewLine + OutputDialog.Text;

        OutputDialog.Text = Thread.CurrentThread.ManagedThreadId + Environment.NewLine + OutputDialog.Text;
    }

UI 的 xml 代码

<Grid>
    <StackPanel>
        <Button Click="AsyncTask">Execute now</Button>
        <TextBox Name="OutputDialog" Background="Gray" Foreground="Yellow" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Stretch">
        </TextBox>
    </StackPanel>
</Grid>
4

1 回答 1

0

在等待之后,流程被安排在调用线程上,因此您不需要在 T2 中调用 Invoke。如果您想继续 T1 的线程,请使用.ConfigureAwait(continueOnCapturedContext: false)

于 2014-06-20T10:23:46.013 回答