Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 使用System.Threading.Task将工作项排队到线程池_.net_Multithreading_Task Parallel Library_Threadpool_Portable Class Library - Fatal编程技术网

.net 使用System.Threading.Task将工作项排队到线程池

.net 使用System.Threading.Task将工作项排队到线程池,.net,multithreading,task-parallel-library,threadpool,portable-class-library,.net,Multithreading,Task Parallel Library,Threadpool,Portable Class Library,我想知道在.NET4.5中,使用System.Threading.Task对象将工作项(委托)排队到线程池的最直接的方法是哪种(如果有的话)。本质上,我想做的是用Tasks复制ThreadPool.QueueUserWorkItem()方法的排队功能。如果我错了,请纠正我,但据我所知,使用此方法排队的工作项保证按其排队顺序执行(对于多处理器场景,可能我完全错了)。我必须使用Tasks编写行为相同的代码 我正在开发一个可移植类库,因此我不能使用ThreadPool.QueueUserWorkIte

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


我正在开发一个可移植类库,因此我不能使用
ThreadPool.QueueUserWorkItem()
,但我必须依赖
Task
s来实现这一目标。你有什么建议吗?默认任务计划程序是否适合此要求?

您所问的正是任务已经完成的任务。任务本质上是lambda的包装器,默认情况下,它排队在线程池上执行。除此之外,任务还添加了延续、异常处理、取消和许多方便的函数,使多线程变得更加容易

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

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

编辑

我从一开始就没有注意到便携式部分。所以问题是“PCL是否提供使用线程池的TaskScheduler,还是我必须创建自己的任务调度器”

.NET 4+提供了ThreadPoolTaskScheduler。不幸的是,PCL子集中似乎缺少这一点。看起来您可能需要创建自己的TaskScheduler或使用Nuget包来添加特定于平台的实现

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

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

在.NET4.0中,TaskScheduler.Default返回ThreadPoolTaskScheduler的实例,ThreadPoolTaskScheduler是一个内部类。在PCL子集中,TaskScheduler.Default返回null,ThreadPoolTaskScheduler不可用

ThreadPoolTaskScheduler的源代码可能可以从Microsoft的参考源服务器获得,但您也可以在

我创建了一个PCL类,该类返回一个新任务,并从.NET4.5控制台应用程序调用它,以查看它将使用什么TaskScheduler。我发现PCL类实际上使用了ThreadPoolTaskScheduler


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

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


Task
s(使用默认的
TaskScheduler
)更复杂,因为它们使用线程本地队列,以后进先出的顺序处理。如果要确保所有
任务都进入全局FIFO队列,可以使用。但是,它也没有具体说明它的作用,因此细节可能会改变。

事实上,我最终得出了相同的结论,一个定制的
任务调度程序
是一条出路,唯一的问题是,由于缺少
线程池,在一个可移植类库项目中实现一个任务调度程序有点困难。我只能通过引用可移植类库的特定于平台的库中的依赖项注入来实现它。@GabrielS.,我很困惑。
Task.Factory.StartNew(…)
有什么问题?它被列为可移植类库所支持的。它与调度程序有关,而不是任务本身。抽象类TaskScheduler可用,但它返回
null
作为当前和默认实例。除了“工作窃取魔法和多队列处理”之外,可移植库中缺少了大多数平台默认的具体ThreadPoolTaskScheduler类这意味着
Task
s将不会按照计划的顺序执行。@svick将
TaskScheduler
的自定义实现设置为1-like-,这是否意味着它将充当串行FIFO队列?请注意,问题是关于可移植库的,您甚至可能没有任何TaskScheduler的实现可供使用。Gabriel本质上是在问“是否有一个TaskScheduler在PCL中使用线程池,或者我必须为每个目标平台使用自己的线程池”@PanagiotisKanavos这不是我理解这个问题的方式。它不要求
线程池
,而是要求以先进先出的方式安排
任务。而
preferfairity
(似乎在PCLs中可用)正是这样做的。@svick实际上是对的,我只提到了
ThreadPool
,作为一个(可能不太好)的例子,
任务的FIFO调度就是我要找的。我将尝试查看
preferfairity
选项是否确实是我的可移植类库所针对的多个平台上默认调度程序的解决方案。@svick不幸的是,
preferfairity
-顾名思义-无法确保FIFO排序,至少在Windows Phone 8上不是这样,我只是尝试了一下。毕竟,自定义任务计划