TPL 是否可以在多个线程上运行任务?

2024-03-29

欢迎特定于 Mono/Xamarin 的答案。

我正在使用 Task.Run() 运行 System.Threading.Tasks。 TPL 是否会在任务执行的生命周期内将创建的任务分配给单个线程?或者创建的任务是否有可能在运行时被抢占,然后再次调度到不同的线程上?

Thread.CurrentThread.ManagedThreadId 在任务的生命周期中是否保持不变?

对于长时间运行的任务,答案是否不同?

有没有办法控制TPL这方面的行为?


TPL 是否会在任务执行的生命周期内将创建的任务分配给单个线程?

指导方针是同步部分工作在单个线程上运行。因此,如果您将同步委托传递给Task.Run,它将全部在单个线程上运行:

await Task.Run(() => Thread.Sleep(5000)); // same thread after sleep

但是,如果您有异步代码,则每个await是代码中方法暂停的位置。当该方法恢复时,它将在线程池线程(可能是不同的线程)上恢复。

await Task.Run(async () => await Task.Delay(5000)); // thread may change

长时间运行的标志(不能传递给Task.Run) 不会影响此行为,因为它仅适用于第一个同步部分。

控制这个的正常方法是使用自定义TaskScheduler or SynchronizationContext。然而,在走这条路之前,您可能需要考虑另一种方法。应该有一个比强制该方法回到同一线程更好的解决方案。例如,线程仿射同步原语都具有async- 兼容的等价物,线程本地存储可以用闭包/类字段/逻辑调用上下文等替换。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TPL 是否可以在多个线程上运行任务? 的相关文章