开发者

How can a TPL task send intermediate results to the parent thread?

开发者 https://www.devze.com 2023-04-10 02:58 出处:网络
I am working with TPL and need to have a long running TPL task send results to the parent UI thread without terminating. I have tried several approaches and have been googling quite a bit. Does anyone

I am working with TPL and need to have a long running TPL task send results to the parent UI thread without terminating. I have tried several approaches and have been googling quite a bit. Does anyone know how to make this happen with T开发者_如何学运维PL?


You could pass in a delegate to call with periodic results, and a SynchronizationContext which the task could use to invoke the callback on the correct thread. That's basically the way that BackgroundWorker does it (and the way that the async feature of C# 5 will "know" where to call you back) - it captures SynchronizationContext.Current on the calling thread, then calls Post (IIRC) to post a message to the right context. You then just need to wrap the original callback in a SendOrPostCallback which executes it when it's got to the right thread.

EDIT: Sample program:

using System;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        Form form = new Form();
        Label label = new Label();
        form.Controls.Add(label);
        form.Load += delegate { HandleLoaded(label); };
        Application.Run(form);
    }

    static void HandleLoaded(Label label)
    {
        Action<string> callback = text => label.Text = text;
        StartTask(callback);
    }

    static void StartTask(Action<string> callback)
    {
        SendOrPostCallback postCallback = obj => callback((string) obj);
        SynchronizationContext context = SynchronizationContext.Current;

        Task.Factory.StartNew(() => {
            for (int i = 0; i < 100; i++)
            {
                string text = i.ToString();
                context.Post(postCallback, text);
                Thread.Sleep(100);
            }
        });
    }
}


Depending on the application you are using there might be different approaches.

  • WinForms: Control.Invoke
  • WPF/Silverlight/WP7 and derivates: Dispatcher.Invoke
  • Some other type of application: define what UI thread means first?
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号