How to update UI from child tasks in WinForms

前端 未结 2 1739
心在旅途
心在旅途 2020-12-17 15:41

I\'ve got a simple little winforms app that performs a long running process on another thread via a TPL Task. During this long running process I\'d like to update the UI (t

相关标签:
2条回答
  • 2020-12-17 16:11

    Yes, you can explicitly call BeginInvoke on the Window/Control that you want to communicate with. In your case this would look like this:

    this.textBox.BeginInvoke(new Action(() =>
    {
       this.textBox.Text = "From child task.";
    }));
    
    0 讨论(0)
  • 2020-12-17 16:19

    You're passing the TaskScheduler as state (or antecedent, as you called it). That doesn't make much sense.

    I'm not sure what exactly do you want to do, but you need to specify the TaskScheduler when you're starting the Task, not when you're creating it. Also, it seems that childTask doesn't have to be a field:

    var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
    
    Task childTask = null;
    
    Task.Factory.StartNew(
        () =>
        {
            Thread.Sleep(1000);
            childTask.Start(scheduler);
            Thread.Sleep(1000);
        });
    
    childTask = new Task(
        () =>
        {
            Thread.Sleep(2000);
            textBox1.Text = "From child task";
        });
    

    Of course, all this is going to be much easier with C# 5 and await:

    public Form1()
    {
        InitializeComponent();
    
        StartAsync();
    }
    
    private async void StartAsync()
    {
        // do some work
        await Task.Run(() => { Thread.Sleep(1000); });
    
        // start more work
        var moreWork = Task.Run(() => { Thread.Sleep(1000); });
    
        // update the UI, based on data from “some work”
        textBox1.Text = "From async method";
    
        // wait until “more work” finishes
        await moreWork;
    }
    

    You can't make async constructor, but you can run an async method from it. “Doing work” doesn't run on the UI thread, because it was started explicitly through Task.Run(). But since StartAsync() was called directly, it executes on the UI thread.

    0 讨论(0)
提交回复
热议问题