Accessing UI controls in Task.Run with async/await on WinForms

后端 未结 6 1517
忘了有多久
忘了有多久 2020-11-29 04:57

I have the following code in a WinForms application with one button and one label:

using System;
using System.IO;
using System.Threading.Tasks;
using System.         


        
6条回答
  •  盖世英雄少女心
    2020-11-29 05:31

    Try this

    private async Task Run()
    {
        await Task.Run(async () => {
           await File.AppendText("temp.dat").WriteAsync("a");
           });
        label1.Text = "test";
    }
    

    Or

    private async Task Run()
    {
        await File.AppendText("temp.dat").WriteAsync("a");        
        label1.Text = "test";
    }
    

    Or

    private async Task Run()
    {
        var task = Task.Run(async () => {
           await File.AppendText("temp.dat").WriteAsync("a");
           });
        var continuation = task.ContinueWith(antecedent=> label1.Text = "test",TaskScheduler.FromCurrentSynchronizationContext());
        await task;//I think await here is redundant        
    }
    

    async/await doesn't guarantee that it will run in UI thread. await will capture the current SynchronizationContext and continues execution with the captured context once the task completed.

    So in your case you have a nested await which is inside Task.Run hence second await will capture the context which is not going to be UiSynchronizationContext because it is being executed by WorkerThread from ThreadPool.

    Does this answers your question?

提交回复
热议问题