欢迎特定于 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(使用前将#替换为@)