从任务并行库问题更新UI

时间:2013-06-05 12:04:52

标签: c# task-parallel-library

我正在学习TPL的艺术。所以我尝试从TPL以增量方式更新UI,但我无法做到正确。这是我正在使用的代码:

    int i = 0, flag = 5;
    var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.StartNew(() =>
    {
        while (i < flag)
        {
            Task.Factory.StartNew(() =>
            {
                this.Text = i.ToString();
                //System.Threading.Thread.SpinWait(50000000);
            }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
            i++;
            System.Threading.Thread.Sleep(1000);

        }
    }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);

我正在尝试以增量方式更新Windows标题栏UI。代码运行没有例外但是UI直到我的值变为5才更新。我想要显示它; 1,然后2,依此类推,直到我为5。

当我运行我的程序时,我注意到我的程序会挂起,直到任务完成或完成。

在使用任务时更新UI时我做错了什么?

另一种方法1

        Task.Factory.StartNew(() =>
        {
            Parallel.For(1, 6, i =>
            {
                System.Threading.Thread.SpinWait(500000000);  do work here   
                BeginInvoke((Action)delegate { this.Text = i.ToString(); });
            });
        });  

另一种方法2

int i = 0, flag = 5;
            var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
            Task.Factory.StartNew(() =>
            {
                while (i < flag)
                {
                    Task.Factory.StartNew(() =>
                    {
                        this.Text = i.ToString();
                    }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
                    i++;
                    System.Threading.Thread.SpinWait(50000000); // do work here   


                }
            }); // <---- Removed arguments (specifically uiScheduler)

1 个答案:

答案 0 :(得分:4)

您正在告诉任务在启动初始任务时使用uiScheduler上下文。删除它,你的代码应该没问题。

int i = 0, flag = 5;
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
    while (i < flag)
    {
        Task.Factory.StartNew(() =>
        {
            this.Text = i.ToString();
        }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
        i++;
        System.Threading.Thread.Sleep(1000);

    }
}); // <---- Removed arguments (specifically uiScheduler)