我有一个 C#/.NET 4.5 应用程序,它可以处理大约 15,000 个彼此独立的项目。每个项目都有一个相对较小的 cpu 工作要做(不超过几毫秒)和 1-2 个 I/O 调用到在带有 SQL Server 2008 后端的 .NET 4.5 中实现的 WCF 服务。我假设他们会将无法足够快地处理的并发请求排队?这些 I/O 操作可能需要几毫秒到一整秒不等。然后工作项有更多的 cpu 工作(少于 100 毫秒)并且完成了。
我在一台具有超线程的四核机器上运行它。使用任务并行库,我试图通过异步运行这些操作并并行完成 CPU 工作,尽可能少地等待 I/O,从而获得机器的最佳性能。
在没有并行进程和异步操作的情况下,应用程序需要大约 9 个小时才能运行。我相信我可以将此过程加快到一小时或更短时间,但我不确定我是否以正确的方式进行此操作。
在 .NET 中完成每个项目的最佳方法是什么?我是否应该创建 15000 个线程并让它们完成上下文切换的所有工作?或者我应该只创建 8 个线程(我有多少个逻辑核心)然后那样做?对此的任何帮助将不胜感激。
最佳答案
我通常的建议是 TPL Dataflow。
您可以将 ActionBlock
与 async
操作一起使用,并将并行度设置为您需要的最高水平:
var block = new ActionBlock<WorkItem>(wi =>
{
DoWork(wi);
await Task.WhenAll(DoSomeWorkAsync(wi), DoOtherWorkAsync(wi));
},
new ExecutionDataflowBlockOptions{ MaxDegreeOfParallelism = 1000 });
foreach (var workItem in workItems)
{
block.Post(workItem);
}
block.Complete();
await block.Completion;
通过这种方式,您可以测试和调整 MaxDegreeOfParallelism
,直到找到最适合您特定情况的数字。
对于并行度高于核心的 CPU 密集型工作没有帮助,但对于 I/O(和其他异步操作),如果您的 CPU 密集型工作很短,那么我至少会选择 1000。
关于c# - 处理 15000 个工作项的最佳方式,每个工作项需要 1-2 次 I/O 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30649101/