为什么在UI线程上调用启动新任务

时间:2015-12-06 19:35:05

标签: c# .net multithreading task-parallel-library

Task t = new Task(() =>
{
    //I would expect this to be on a worker thread, but it's not!
    Thread.Sleep(1000);
});

Task test = new Task(() =>
{
    Thread.Sleep(1000);
});

test.ContinueWith(x =>
{
    //Do some UI Updates here, but also start another Task running.
    t.Start();
}, TaskScheduler.FromCurrentSynchronizationContext());

test.Start();

为什么在UI线程上调用t。我理解我创建了一个针对Task的延续test,它在UI线程上被正确调用,但我正在开始一个新的任务运行。现在我知道我可以通过将TaskScheduler.Default指定为针对t.Start的重载方法来解决这个问题,但为什么新的Task会在ui线程上启动?

2 个答案:

答案 0 :(得分:5)

  

但是为什么新的Task开始使用ui线程?

因为除非另外指定,否则在任务上调用Start会调度当前TaskScheduler上的任务,在您的情况下,该任务是使用{SynchronizationContext创建的UI线程TaskScheduler.FromCurrentSynchronizationContext()的正面。 1}}。

  

启动Task,将其安排执行到当前TaskScheduler

来自Task.Start Method

如果您希望将该任务安排在与当前任务不同的TaskScheduler上,您可以将其作为参数传递:

t.Start(TaskScheduler.Defualt);

注意:几乎没有可以想象使用Task.Start是最佳解决方案。你应该重新考虑这条道路。

答案 1 :(得分:3)

不要使用Task.Start方法。此外,如果您想延迟任务,请使用Task.Delay,如下所示:

Task.Delay(TimeSpan.FromSeconds(1)) //Wait 1 second
    .ContinueWith(t => DoSomeUIWork(), TaskScheduler.FromCurrentSynchronizationContext()) //execute something on the UI thread
    .ContinueWith(t => DoSomeBackgroundWork()); //Then do some background work