0

更新今は問題ありません。Dispatcher.Invoke メソッドの内部と外部で返される theadID が異なることに気付きませんでした。

私の理解では、非同期を使用する場合、待機中のタスク T1 は別のスレッドで実行され、待機中のコードはタスク T2 として T1 の ContinueWith でラップされます。したがって、以下のコードでは threadcontextID が異なると思います。ただし、以下のコードは同じ ThreadContextID を生成します。私の理解は間違っていますか?

また、T1 では Dispatcher を使用する必要があるのに、T2 ではメイン UI を直接更新できるのはなぜですか? threadContext スイッチは async/await でどのように機能しますか? ありがとう。

更新: T1 のコードは、VS Debug Thread ビューの 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 の xaml コード

<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 に答える