使用Tasks实现BackgroundWorker的RunWorkerCompleted

时间:2011-05-24 15:00:08

标签: .net c#-4.0 backgroundworker task

我有一个WPF MVVM应用程序。在其中一个ViewModel中,我有以下内容:

this.GoCommand = new RelayCommand(() =>
{
    var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

    Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 100; ++i)
            {
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }).ContinueWith(task =>
            {
                // should act like RunWorkerCompleted
                this.DoSecondTask();
            },
            scheduler
        );
});

private void DoSecondTask()
{ 
    Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 100; ++i)
            {
                // repeated task for simplicity
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }).ContinueWith(task =>
            {
                this.Status = "Done.";
            }
        );
}

当我点击绑定到GoCommand的按钮时,我看到进度条从1-100移动。但是,当ContinueWith执行DoSecondTask时,该任务在UI线程中运行。如何更改DoSecondTask函数以在新线程(或UI线程之外)中运行第二个for循环?

1 个答案:

答案 0 :(得分:2)

我在this回答中找到了解决方案。有趣的是,没有工作:

private void DoSecondTask()
{ 
    Task.Factory.StartNew(_ =>
        {
            for (int i = 0; i < 100; ++i)
            {
                // repeated task for simplicity
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }, TaskScheduler.Default).ContinueWith(task =>
            {
                this.Status = "Done.";
            }
        );
}

确实

private void DoSecondTask()
{ 
    Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 100; ++i)
            {
                // repeated task for simplicity
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).ContinueWith(task =>
            {
                this.Status = "Done.";
            }
        );
}