组合命令以并行执行链

时间:2014-12-28 16:34:15

标签: c# system.reactive command-pattern chain-of-responsibility

我正在寻找适合这种情况的模式。

我需要以这种方式从HDD获取处理文件。

  1. 加载文件
  2. 分析文件
  3. 根据分析结果验证文件
  4. 根据验证结果将文件导入应用
  5. 此过程将来可能会发生变化。

    我的想法是为每个文件操作创建命令(命令模式)。

    • LoadFileCommand:IFileCommand
    • AnalyzeFileCommand:IFileCommand
    • ValidateFileCommand:IFileCommand
    • ImportFileCommand:IFileCommand

    代码:

    public interface IFileCommand
    {
      FileCommandResult Execute();
      void Abort();
    }
    public class FileCommandResult
    { 
      FileInfo File{get;}
      bool Sucesss{get;}
      string Error{get;}
    }
    

    我需要使用命令创建流程(带命令的链)。

    我尝试用于此目的的可靠性模式链但可能存在更好的模式或设计。

    如果有可能我想使用Rx并且并行执行会很好。

    我想实现这个目标:

    var data = new List<FileInfo>();
    
    var process = new List<IFileCommand>{new LoadFileCommand(), new AnalyzeFileCommand(), new ValidateFileCommand(), new ImportFileCommand()};
    
    var processor = new FileProcessor();
    
    IEnumerable<IFileCommandResult> results = processor.Execute(process, data);
    

    任何想法。

1 个答案:

答案 0 :(得分:0)

为什么要为此使用Rx?如果要将操作表示为一系列命令,则只需使用LINQ来应用命令链。如果您希望它们并行运行,那么只需使用PLINQ,TPL或Parallel.ForEach。您也可以查看TPL Dataflow

以下是解决问题的3种方法。注意我没有实现错误处理或弄乱你的Abort方法,我对你的Execute方法采取了一些自由,因为你的方法无法使用。我现在假设Execute具有此签名:FileInfo Execute(FileInfo)并且如果失败则抛出异常。

IEnumerable<FileInfo> data = ...;
IEnumerable<IFileCommand> process = ...;

// PLINQ
var results = data
    .AsParallel()
    .Select(dataItem => process.Aggregate(dataItem, (d, p) => p.Execute(d)))
    .ForAll(dataItem => import(dataItem));


// Parallel.Foreach
Parallel.Foreach(data, dataItem => import(process.Aggregate(dataItem, (d, p) => p.Execute(d))));

// TPL
var tasks = data
    .Select(dataItem => Task.Run(() => import(process.Aggregate(dataItem, (d, p) => p.Execute(d)))));
await Task.WhenAll(tasks);