How can a TPL task send intermediate results to th

2019-05-14 17:43发布

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 TPL?

2条回答
神经病院院长
2楼-- · 2019-05-14 18:27

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);
            }
        });
    }
}
查看更多
Luminary・发光体
3楼-- · 2019-05-14 18:27

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

查看更多
登录 后发表回答