批量
今天
.NET 4.0
第1步非常快。
对于相同尺寸的文件,步骤2和3的长度大约相同(平均0.1秒)
在步骤3中插入使用BackGroundWorker并等待最后完成
其他一切都在主线上。
在很大的负荷上会做几百万次。
需要步骤3为序列号,顺序为1 这是为了防止SQL表PK索引破裂 并行尝试了第3步,压缩指数使其死亡 这些数据按PK排序 其他索引在加载开始时被删除,然后在加载结束时重建。
此过程无效的地方是文本大小发生变化时 从文件到文件的文本大小确实发生了巨大变化 我想要的是队列1和2所以3尽可能地保持忙碌。
需要步骤3将文件排队,以便它们在1中排队(即使它等待)。
内存管理需要最大队列大小(如4-10)。
希望步骤2与最多4个并发进行并行。
迁移到.NET 4.5。
询问有关如何实施此方法的一般指导?
我知道这是一个生产者消费模式 如果这不是生产者消费者模式,请告诉我,以便我可以更改标题。
答案 0 :(得分:2)
我认为TPL Dataflow是一个很好的方法:
对于第2步,您可以使用TransformBlock
MaxDegreeOfParallelism
设置为4而BoundedCapacity
也设置为4,以便在工作时其队列为空。它会以与它们相同的顺序生成项目,您不必为此做任何特殊操作。对于第3步,请使用ActionBlock
,并将BoundedCapacity
设置为限制。然后将两者链接在一起并开始向TransformBlock
发送项目,理想情况下使用类似await stepTwoBlock.SendAsync(…)
的内容,以便在队列已满时异步等待。
在代码中,它看起来像:
async Task ProcessData()
{
var stepTwoBlock = new TransformBlock<OriginalText, ParsedText>(
text => Parse(text),
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 4,
BoundedCapacity = 4
});
var stepThreeBlock = new ActionBlock<ParsedText>(
text => LoadIntoDatabase(text),
new ExecutionDataflowBlockOptions { BoundedCapacity = 10 });
stepTwoBlock.LinkTo(
stepThreeBlock, new DataflowLinkOptions { PropagateCompletion = true });
// this is step one:
foreach (var id in IdsToProcess)
{
OriginalText text = ReadText(id);
await stepTwoBlock.SendAsync(text);
}
stepTwoBlock.Complete();
await stepThreeBlock.Completion;
}