Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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
C# 4.0 限制流式资源并行操作的在制品_C# 4.0_Concurrency_Task Parallel Library_Yield Return - Fatal编程技术网

C# 4.0 限制流式资源并行操作的在制品

C# 4.0 限制流式资源并行操作的在制品,c#-4.0,concurrency,task-parallel-library,yield-return,C# 4.0,Concurrency,Task Parallel Library,Yield Return,我最近发现自己使用了SemaphoreSlim类来限制(大型)流式资源上可并行操作的进行中的工作: // The below code is an example of the structure of the code, there are some // omissions around handling of tasks that do not run to completion that should be in production code SemaphoreSlim semap

我最近发现自己使用了
SemaphoreSlim
类来限制(大型)流式资源上可并行操作的进行中的工作:

// The below code is an example of the structure of the code, there are some 
// omissions around handling of tasks that do not run to completion that should be in production code

SemaphoreSlim semaphore = new SemaphoreSlim(Environment.ProcessorCount * someMagicNumber);
foreach (var result in StreamResults()) 
{
  semaphore.Wait();
  var task = DoWorkAsync(result).ContinueWith(t => semaphore.Release());
  ...
}
这是为了避免将太多的结果带入内存,以及程序无法处理(通常通过OutOfMemoryException证明)。尽管代码可以正常工作,性能也相当不错,但它仍然感觉笨拙。值得注意的是,
someMagicNumber
乘法器虽然通过评测进行了调整,但可能不是最佳的,并且对
doorksync
实现的更改没有弹性

正如线程池可以克服调度许多事情以执行的障碍一样,我希望能够克服调度许多事情以基于可用资源加载到内存中的障碍


由于无法确定是否会发生OutOfMemoryException,我明白我所寻找的可能只能通过统计手段实现,甚至根本无法实现,但我希望我遗漏了一些东西。

这里我要说的是,你可能对这个问题想得太多了。超调的后果相当严重(程序崩溃)。过低的后果是,该计划可能会放缓。只要您还有一些超出最小值的缓冲区,进一步增加缓冲区通常不会有什么影响,除非管道中该任务的处理时间非常不稳定

如果您的缓冲区不断被填满,这通常意味着管道中它之前的任务执行速度比它后面的任务快,因此即使没有相当小的缓冲区,它也可能总是确保它后面的任务有一些工作。获得90%的缓冲好处所需的缓冲区大小通常非常小(可能有几十个项目),而获得OOM错误所需的那一方则比magnate高出6+个订单。只要你在这两个数字之间(这是一个相当大的范围),你就会很好


只需运行静态测试,选择一个静态数字,或者为“以防万一”添加几个额外的百分比,您就应该很好了。最多,我会将一些神奇的数字移动到配置文件中,以便在输入数据或机器规格发生根本性变化的情况下,无需重新编译就可以更改它们。

您是否介意
doworksync()
实际上是同步执行的?你会用C#5吗?这与
收益返回有什么关系?@svick我宁愿DoWorkAsync没有同步执行,因为网络IO是执行的,并且可以使用完成端口线程。对收益率返回进行标记只是因为它是如何返回
StreamResults
的结果。我不能使用.C#5(或4.5,或MS现在称之为的任何版本!),只使用C#4.0。它称为C#5.0,将与.Net 4.5一起发布。是的,.Net版本号可能会让人困惑。如果它正在进行网络IO,那么找到正确的并行度几乎取决于您。
ThreadPool
(或TPL中的任何东西)不能真正为您做到这一点。我认为问题不在于缓冲区的大小,而在于并行执行。@svick两者都有关系。有许多相关操作并行运行,创建管道。当一个任务完成一个工作单元时,它将结果传递给下一个任务,下一个任务对其执行另一个工作单元,并将其传递给管道中的下一个操作员。所有这些任务同时工作。每个任务之间都有一个缓冲区,这样在开始下一个工作单元之前,它们就不需要等待下一个任务收到结果;如果所有任务的工作时间都不完全相同,那么这将减少等待时间。我不确定你在说什么,但我很确定这不是问题中的代码。没有任何管道或类似的东西。