jef*_*091 8 c# mono multithreading xamarin.ios xamarin
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
Run Code Online (Sandbox Code Playgroud)
但是,如果您有异步代码,则 everyawait都是代码中暂停方法的位置。当该方法恢复时,它将在线程池线程(可能是不同的线程)上恢复。
await Task.Run(async () => await Task.Delay(5000)); // thread may change
Run Code Online (Sandbox Code Playgroud)
长时间运行标志(无法传递给Task.Run)不会影响此行为,因为它仅适用于第一个同步部分。
控制这一点的正常方法是使用自定义TaskScheduler或SynchronizationContext. 然而,在走这条路之前,您可能需要考虑另一种方法。应该有一个比强制该方法回到同一线程更好的解决方案。例如,线程仿射同步原语都具有async兼容的等效项,线程本地存储可以用闭包/类字段/逻辑调用上下文等替换。