3

线程池,我想知道哪些(如果有的话)是使用System.Threading.Task对象排队的工作项目(委托)的线程池在.NET 4.5的最直接的方法。我想要做的实质是将ThreadPool.QueueUserWorkItem()方法的排队功能与Task s一起复制。如果我错了,请纠正我的错误,但据我所知,使用此方法排队的工作项目保证按排入队列的顺序执行(也许我对多处理器方案完全错误)。我必须编写表现相同的代码,使用Task s。排队的工作项目使用System.Threading.Task

我工作的便携式类库,所以这就是为什么我不能用ThreadPool.QueueUserWorkItem(),而是我必须依靠Task S表示这一目标。你会建议什么技术?默认任务调度程序是否适合此要求?

+0

我开始认为PCL为每个平台本身选择适当的TaskScheduler。检查我的答案的编辑,但我将不得不测试更多 –

回答

1

你问什么是任务已经做了什么。 Task本质上是一个lambda的包装器,默认情况下会被排队等待在ThreadPool上执行。最重要的是,任务添加了延续,异常处理,取消和许多便利功能,使多线程更容易。

如果你不想使用线程池,你可以创建自己的TaskScheduler,并创建一个新的任务时使用它。 TaskScheduler本质上接收一个Task并安排它执行。

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

编辑

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

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

不知怎的,我觉得ThreadPoolTask​​Scheduler将是一个不错的选择对于一款Windows Phone项目

使用ReSharper的和.NET的调试符号一些diggind之后,我觉得PCL本身找到任何可用平台的TaskScheduler实现。

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

为ThreadPoolTask​​Scheduler的源代码probalby可从微软的参考源服务器,但你也可以很快在dotnetframework.org

浏览它,我创建了一个返回一个新的任务PCL类,并把它称为从.NET 4.5的控制台应用程序来查看它将使用的TaskScheduler。我发现PCL类实际上使用了ThreadPoolTask​​Scheduler。

我还没有与Windows 8或Windows Phone 8的项目尝试这样呢,虽然我怀疑我会得到每个平台的默认的TaskScheduler。

+0

事实上,我最终达到了相同的结论,一个自定义的'TaskScheduler'是要走的路,唯一的问题是它有点痛苦由于缺乏'ThreadPool',在便携式类库项目中实现一个。我只能通过引用可移植类库的平台特定库的依赖注入来实现。 –

+0

@GabrielS,我很困惑。 'Task.Factory.StartNew(...)'有什么问题?它被列为支持便携式类库。 –

+0

这是关于调度程序,而不是任务本身。抽象类TaskScheduler可用,但它返回'null'作为当前和默认实例。具体的ThreadPoolTask​​Scheduler类是大多数平台默认的,它在便携库中是缺少的 –

3

ThreadPool不需要以与预定完全相同的顺序执行委托(至少我没有在文档中找到任何类似的担保)。但据我所知,它几乎是如此表现。

Task s(使用默认的TaskScheduler)更复杂,因为它们使用线程本地队列,它们按LIFO顺序处理。如果你想确保你所有的Task都进入全局FIFO队列,你可以使用TaskCreationOptions.PreferFairness。但是,再次,没有记录具体做什么,所以具体可以改变。

+0

注意的一个问题是关于*便携式*库,在这里你甚至可能不会有任何要使用的TaskScheduler的实现。 Gabriel本质上是问“在PCL中是否有使用ThreadPool的TaskScheduler,还是我必须为每个目标平台推出我自己的”? –

+1

@PanagiotisKanavos这不是我理解这个问题的方式。它不要求'ThreadPool',它要求以一种先进先出的方式来调度Task。 “PreferFairness”(似乎在PCL中可用)就是这样做的。 – svick

+0

@svick实际上,我只提到'ThreadPool'作为一个(可能不是很好)的例子,'Task'的FIFO调度就是我正在寻找的。我会试着看看'PreferFairness'选项是否确实是我的便携式类库所针对的多个平台上默认调度程序的解决方案。 –