在实现管道验证中使用多个BlockingCollection <t>缓冲区</t>

时间:2013-11-06 19:11:19

标签: c# multithreading parallel-processing task

因此,我需要读取大型数据文件的每个记录(行),然后在每个行上应用各种验证规则。因此,我决定看看是否可以使用一些流水线来帮助加快速度,而不仅仅是应用顺序验证。因此,我需要将同一组业务验证规则(目前为5)应用于我的集合中的所有项目。由于无需返回每个验证过程的输出,因此我无需担心将值从一个验证例程传递到另一个验证例程。但是,我确实需要为我的所有验证步骤提供相同的数据,为此,我想出了将相同的数据(记录)复制到5个不同的缓冲区,每个缓冲区将使用这些缓冲区。

以下是我要去的代码。但是我对此应用没有信心,想知道是否有更好的方法来做到这一点?我很感谢你能给予的任何帮助。提前致谢。

public static void LoadBuffers(List<BlockingCollection<FlattenedLoadDetail>> outputs,
            BlockingCollection<StudentDetail> students)
        {
            try
            {
                foreach (var student in students)
                {
                    foreach (var stub in student.RecordYearDetails)
                        foreach (var buffer in outputs)
                            buffer.Add(stub);
                }
            }
            finally
            {
                 foreach (var buffer in outputs)
                     buffer.CompleteAdding();
            }

        }


    public void Process(BlockingCollection<StudentRecordDetail> StudentRecords)
    {

        //Validate header record before proceeding

        if(! IsHeaderRecordValid)
            throw new Exception("Invalid Header Record Found.");
        const int buffersize = 20;
        var buffer1 = new BlockingCollection<FlattenedLoadDetail>(buffersize);
        var buffer2 = new BlockingCollection<FlattenedLoadDetail>(buffersize);
        var buffer3 = new BlockingCollection<FlattenedLoadDetail>(buffersize);
        var buffer4 = new BlockingCollection<FlattenedLoadDetail>(buffersize);
        var taskmonitor = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.NotOnCanceled);

        using (var loadUpStartBuffer = taskmonitor.StartNew(() => LoadBuffers(
            new List<BlockingCollection<FlattenedLoadDetail>>
            {buffer1, buffer2, buffer3, buffer4}, StudentRecords)))
        {
            var recordcreateDateValidationStage = taskmonitor.StartNew(() => ValidateRecordCreateDateActivity.Validate(buffer1));
            var uniqueStudentIDValidationStage =
                taskmonitor.StartNew(() => ValidateUniqueStudentIDActivity.Validate(buffer2));
            var SSNNumberRangeValidationStage =
                taskmonitor.StartNew(() => ValidateDocSequenceNumberActivity.Validate(buffer3));
            var SSNRecordNumberMatchValidationStage =
                taskmonitor.StartNew(() => ValidateStudentSSNRecordNumberActivity.Validate(buffer4));

            Task.WaitAll(loadUpStartBuffer, recordcreateDateValidationStage, uniqueStudentIDValidationStage,
                SSNNumberRangeValidationStage, SSNRecordNumberMatchValidationStage);

        }
    }

事实上,如果我能以这样的方式完成任务,一旦一个人失败,其他所有人都停下来,这对我有很大帮助,但我是这种模式的新手,并试图找出最好的方法处理这个问题我在这里。我是否应该谨慎对待风并让每个验证步骤加载一个输出缓冲区以传递给后续任务?这是一个更好的方式吗?

1 个答案:

答案 0 :(得分:0)

您需要自己回答的第一个问题是,您是否希望改善延迟或吞吐量。

您描绘的策略采用单个项目并对其执行并行计算。这意味着物品的服务速度非常快,但是还要等待轮到他们进入的其他物品。

考虑另一种并行方法。您可以将整个验证过程视为顺序操作,但同时并行处理多个项目。

在我看来,在你的情况下,你会从后一种方法中受益更多,特别是从简单的角度来看,因为我猜测延迟在这里并不重要。