3

我想知道哪种(如果有的话)是使用System.Threading.Task对象将工作项(委托)排队到 .Net 4.5 中的线程池的最直接方式。我想要做的基本上是ThreadPool.QueueUserWorkItem()Tasks 复制方法的排队功能。如果我错了,请纠正我,但据我所知,使用此方法排队的工作项保证按照它们排队的顺序执行(对于多处理器场景,我可能完全错了)。Task我必须使用s编写行为相同的代码。

我正在开发一个可移植的类库,所以这就是我不能使用的原因ThreadPool.QueueUserWorkItem(),而是我必须依靠Tasks 来实现这个目标。你会建议什么技术?默认的任务调度器是否适合这个需求?

4

2 回答 2

4

ThreadPool不需要按照与计划完全相同的顺序执行代表(至少我在文档中没有找到类似的保证)。但据我所知,这几乎就是它的行为方式。

Tasks (使用默认值TaskScheduler)更复杂,因为它们使用线程本地队列,按 LIFO 顺序处理。如果要确保所有Tasks 都进入全局 FIFO 队列,可以使用TaskCreationOptions.PreferFairness. 但同样,它没有记录具体是做什么的,所以细节可能会改变。

于 2013-07-11T18:27:20.453 回答
2

您所问的正是 Tasks 已经在做的事情。Task 本质上是一个 lambda 的包装器,默认情况下它会排队等待在 ThreadPool 上执行。最重要的是,Tasks 添加了延续、异常处理、取消和许多便利功能,使多线程变得更加容易。

如果不想使用ThreadPool,可以创建自己的TaskScheduler,在创建新Task的时候使用。TaskScheduler 本质上是接收一个 Task 并安排它执行。

默认的 TaskScheduler 使用 ThreadPool.QueueUserWorkItem 加上一些工作窃取魔法和多队列处理。其他实现可以使用优先级队列,对最大或最小线程数设置自己的限制,或者他们的作者想要使用的任何技术。

编辑

我从一开始就没有注意到 便携式部分。所以问题是“PCL 是否提供了一个使用 ThreadPool 的 TaskScheduler 还是我必须创建自己的”?

.NET 4+ 提供了 ThreadPoolTask​​Scheduler。不幸的是,这似乎在 PCL 子集中缺失。看起来您可能必须创建自己的 TaskScheduler 或使用 Nuget 包来添加特定于平台的实现。

不知何故,我认为 ThreadPoolTask​​Scheduler 对于 Windows Phone 项目来说是一个糟糕的选择

在使用 Resharper 和 .NET 的调试符号进行一些挖掘之后,我认为 PCL 可以自行找到任何可用的平台 TaskScheduler 实现。

在 .NET 4.0 中,TaskScheduler.Default 返回一个 ThreadPoolTask​​Scheduler 的实例,一个内部 BCL 类。在 PCL 子集中,TaskScheduler.Default 返回 null 并且 ThreadPoolTask​​Scheduler 不可用。

ThreadPoolTask​​Scheduler 的源代码可能可以从 Microsoft 的参考源服务器获得,但您也可以在dotnetframework.org上快速浏览它

我创建了一个返回新任务的 PCL 类,并从 .NET 4.5 控制台应用程序中调用它以查看它将使用什么 TaskScheduler。我发现PCL类实际上使用了ThreadPoolTask​​Scheduler。

我还没有在 Windows 8 或 Windows Phone 8 项目中尝试过这个,尽管我怀疑我会得到每个平台的默认 TaskScheduler。

于 2013-07-11T11:56:22.610 回答