Async ThreadContext ID

474 Views Asked by At

UPDATE Not a Problem now. Didn't realize the theadID returned inside and outside the Dispatcher.Invoke method are different.

From my understanding, when using async, the awaiting task T1 will be executed in a different thread and the code following the await are wrapped as task T2 with a ContinueWith of T1. So I assume the threadcontextID would be different in the code below. However the code below generate the same ThreadContextID. Is my understanding wrong?

Also, why I have to use Dispatcher in T1, but can update the main UI in T2 directly? How does the threadContext switch work in async/await? Thanks.

UPDATE: The code in T1 is executing in the MainThread in the VS Debug Thread view. However, if it is in the Main thread, why I can't update the UI directly? It gives me the CrossThread exception.

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;
    }

xaml code for the UI

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

There are 1 best solutions below

1
On

After the await, the flow is scheduled on the calling thread so that is why you don't need the Invoke in T2. If you want to continue on T1's thread then use .ConfigureAwait(continueOnCapturedContext: false)