Raz*_*t4x 5 c# multithreading task-parallel-library async-await visual-studio-2012
我正在阅读C# 5.0 in nutshell
并在阅读了作者的观点后,我对我应该采用什么感到困惑.我的要求是说我有一个很长时间运行(计算量很大)的任务,例如,计算数百万个文件的SHA1(或其他一些)哈希值,或者实际上任何其他东西都是计算量很大并且可能需要一些时间什么应该是我对发展它的方法(winforms
如果该事项,使用VS 2012,C#5.0) so that I can also report progress to the user
.
以下情景浮现在脑海中......
创建一个Task
(与LongRunning
该计算哈希值,并报告进度,用户选择或者通过实施IProgess<T>
或Progess<T>
或让任务捕捉SynchronizationContext
上下文和张贴到UI.
创建一个Async
类似的方法
async CalculateHashesAsync()
{
// await here for tasks the calculate the hash
await Task.Rung(() => CalculateHash();
// how do I report progress???
}
Run Code Online (Sandbox Code Playgroud)使用TPL(或PLINQ)作为
void CalcuateHashes()
{
Parallel.For(0, allFiles.Count, file => calcHash(file)
// how do I report progress here?
}
Run Code Online (Sandbox Code Playgroud)使用生产者/消费者队列.
真的不知道怎么办?
书中的作者说......
在池化线程上运行一个长时间运行的任务不会造成麻烦.当你并行运行多个长时间运行的任务(特别是那些阻塞的任务)时,性能会受到影响.在这种情况下,通常有比TaskCreationOptions.LongRunnging更好的解决方案
- 如果任务是IO绑定的,TaskCompletionSource和异步函数允许您使用回调而不是线程实现并发.
- 如果任务是计算绑定的,那么生产者/消费者队列可以限制这些任务的并发性,避免其他线程和进程的饥饿.
关于Producer/Consumer
作者说......
生产者/消费者队列在并行编程和一般并发场景中都是一种有用的结构,因为它可以精确控制一次执行多少个工作线程,这不仅有助于限制CPU消耗,还有助于其他资源.
那么,我不应该使用任务,这意味着第一个选项是什么?第二个是最好的选择吗?还有其他选择吗?如果我遵循作者的建议,并实现生产者/消费者,我将如何做到(我甚至不知道如何在我的方案中开始使用生产者/消费者,如果这是最好的方法! )
我想知道是否有人遇到过这种情况,他们将如何实施?如果没有,那么性能最有效和/或易于开发/维护的是什么(我知道这个词performance
是主观的,但我们只考虑它的工作原理,并且效果很好!)
例如,计算数百万个文件的SHA1(或其他一些)哈希值,实际上是长时间运行(计算量很大)的任务
该示例显然具有繁重的CPU(散列)和I/O(文件)组件.也许这是一个非代表性的例子,但根据我的经验,即使是安全散列也比从磁盘读取数据快得多.
如果你只有CPU限制工作,最好的解决方案是Parallel
PLINQ.如果您只有I/O绑定的工作,最好的解决方案是使用async
.如果您有一个更现实和复杂的场景(CPU和I/O都工作),那么您应该将CPU和I/O部件与生产者/消费者队列连接起来,或者使用更完整的解决方案,例如TPL Dataflow.
TPL Dataflow适用于parallel(MaxDegreeOfParallelism
)和async
,并且在每个块之间都有一个内置的生产者/消费者队列.
混合大量I/O和CPU使用时要记住的一件事是,不同的情况会导致大量不同的性能特征.为了安全起见,您需要限制通过队列的数据,这样您就不会遇到内存使用问题.TPL Dataflow内置了对限制通道的支持BoundedCapacity
.
归档时间: |
|
查看次数: |
2277 次 |
最近记录: |