TPL可以在多个线程上运行任务吗? [英] Can the TPL run the Task on more than one thread?

查看:56
本文介绍了TPL可以在多个线程上运行任务吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

欢迎针对Mono/Xamarin的答案.

Mono/Xamarin-specific answers are welcomed.

我正在使用Task.Run()运行System.Threading.Tasks. TPL将在任务执行期间将创建的任务分配给单个线程吗?还是创建的任务在运行时会被抢占,然后在另一个线程上再次进行调度?

I'm running System.Threading.Tasks using Task.Run(). Will The TPL assign the created task to a single thread for the life of the task's execution? Or is it possible that the created task will get preempted while running, and then be scheduled again on a different thread?

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

Will Thread.CurrentThread.ManagedThreadId be constant over the life of a Task?

对于长期运行的任务,答案是否有所不同?

Is the answer different for long-running tasks?

在这方面是否有办法控制TPL行为?

Is there a way to control TPL behavior in this regard?

推荐答案

TPL将在任务执行的整个生命周期中将创建的任务分配给单个线程吗?

Will The TPL assign the created task to a single thread for the life of the task's execution?

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

The guideline is that synchronous portions of work run on a single thread. So, if you pass a synchronous delegate to Task.Run, it will all run on a single thread:

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

但是,如果您有异步代码,则每个await都是代码中该方法被挂起的位置.方法恢复后,将在线程池线程(可能是其他线程)上恢复.

However, if you have asynchronous code, every await is a location in the code where the method is suspended. When the method resumes, it will resume on a thread pool thread (which may be a different thread).

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

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

The long-running flag (which cannot be passed to Task.Run) does not affect this behavior because it only applies to the first synchronous portion.

控制此操作的通常方法是使用自定义TaskSchedulerSynchronizationContext.但是,在走这条路之前,您可能需要考虑另一种方法.与将方法强制返回到同一线程相比,应该有更好的解决方案.例如,仿射仿射同步原语都具有与async兼容的等效项,可以用闭包/类字段/逻辑调用上下文等替换线程本地存储.

The normal way to control this is by using a custom TaskScheduler or SynchronizationContext. However, before going down that road, you may want to consider an alternative approach. There should be a better solution than forcing the method back onto the same thread. For example, thread-affine synchronization primitives all have async-compatible equivalents, thread-local storage can be replaced by closures / class fields / logical call context, etc.

这篇关于TPL可以在多个线程上运行任务吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆