0

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

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 类,但是 Tasks 呢?

4

4 回答 4

1

您可以随时在 DoSth() 中调用其他方法

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

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

于 2013-03-28T12:27:02.927 回答
1

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

Task.Factory.StartNew(() => DoSomethingOnGUI(), TaskScheduler.FromCurrentSynchronizationContext());
于 2013-03-28T12:28:55.407 回答
0

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

因此,为了从 UI 中的任何 UI 线程执行某些操作,您需要以某种方式将 msg 注入线程,例如 htis winform 示例:

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

您正在使用的 waterever UI 您将需要一个类似的系统。

于 2013-03-28T13:06:14.793 回答
0

有了windows Form和progressBar1组件,就可以使用TPLIProgress接口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;
    }
于 2013-03-28T12:45:01.980 回答