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

本文关键字:调用 启动 新任务 线程 UI 为什么 | 更新日期: 2023-09-27 18:26:02

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。我知道我创建了一个针对 test 的延续Task,该延续在 UI 线程上正确调用,但随后我正在开始运行一个新任务。现在我知道我可以通过指定 TaskScheduler.Default 作为针对 t.Start 的重载方法来解决这个问题,但是为什么要在 ui 线程上开始使用新的Task

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

但是,为什么新Task在 UI 线程上开始呢?

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

启动Task,调度执行到当前TaskScheduler

从任务启动方法

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

t.Start(TaskScheduler.Defualt);

注意:几乎没有任何情况可以想象使用Task.Start是最佳解决方案。您可能应该重新考虑这条途径。

不要使用 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