c# . net 4 Can Task在UI线程上提供通知

本文关键字:线程 通知 UI net Can Task | 更新日期: 2023-09-27 18:06:31

我在我的应用程序中使用任务类。这不是WPF应用程序!问题是是否有可能在UI线程上从任务体调用函数,像这样:

var task = new Task(() => DoSmth(1));
task.Start();
public void DoSmth(int arg)
    {
        //smth
        CallNotifFuncOnUIThread(() => Notify(1));
        //smth ELSE
        CallNotifFuncOnUIThread(() => Notify(2));//notify AGAIN
        //smth ELSE
    }
public void Notify(int arg)
    {
        progressBar1.Value = arg;
    }

或者这个问题还有别的解决办法?我知道BackgroundWorker类,但任务呢?

c# . net 4 Can Task在UI线程上提供通知

你可以在DoSth()中调用其他方法

Dispatcher.Invoke(...);
Dispatcher.BeginInvoke(...);

也可以让Task.ContinueWith(...)在任务处理完成后做某事

如果您有一个任务,您可以通过提供正确的调度程序在gui线程上启动它:

Task.Factory.StartNew(() => DoSomethingOnGUI(), TaskScheduler.FromCurrentSynchronizationContext());

UI通常是STA参见:http://msdn.microsoft.com/en-us/library/windows/desktop/ms680112(v=vs.85).aspx

所以为了在UI中从无UI线程做一些事情,你需要以某种方式注入msg到线程中参见以下示例:

http://weblogs.asp.net/justin_rogers/articles/126345.aspx

无论你使用什么UI,你都需要一个类似的系统。

使用windows Form和progressBar1组件,您可以使用TPL IProgress接口为Task

    private void Form1_Load(object sender, EventArgs e)
    {
        Progress<int> progress = new Progress<int>();
        var task = Alg(progress);
        progress.ProgressChanged += (s, i) => { UpdateProgress(i); };
        task.Start();
    }
    public void Notify(int arg)
    {
        progressBar1.Value = arg;
    }
    public static Task Alg(IProgress<int> progress)
    {
        Task t = new Task
        (
            () =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(100);
                    ((IProgress<int>)progress).Report(i);
                }
            }
        );
        return t;
    }