Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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# 通过并行执行组合命令链_C#_System.reactive_Command Pattern_Chain Of Responsibility - Fatal编程技术网

C# 通过并行执行组合命令链

C# 通过并行执行组合命令链,c#,system.reactive,command-pattern,chain-of-responsibility,C#,System.reactive,Command Pattern,Chain Of Responsibility,我正在寻找适合这种情况的模式 我需要用这种方式处理硬盘上的文件 加载文件 分析文件 基于分析结果验证文件 根据验证结果将文件导入应用程序 这个过程在将来可能会改变 我的想法是为每个文件操作创建命令(命令模式) LoadFileCommand:IFileCommand AnalyzeFileCommand:IFileCommand ValidateFileCommand:IFileCommand ImportFileCommand:IFileCommand 代码: 我需要用命令创建流程(用命令

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

我需要用这种方式处理硬盘上的文件

  • 加载文件
  • 分析文件
  • 基于分析结果验证文件
  • 根据验证结果将文件导入应用程序
  • 这个过程在将来可能会改变

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

    • LoadFileCommand:IFileCommand
    • AnalyzeFileCommand:IFileCommand
    • ValidateFileCommand:IFileCommand
    • ImportFileCommand:IFileCommand
    代码:

    我需要用命令创建流程(用命令链)

    为此,我尝试使用责任链模式,但可能存在更好的模式或设计

    如果可能的话,我想使用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);
    
    var data=newlist();
    var process=new List{new LoadFileCommand(),new AnalyzeFileCommand(),new ValidateFileCommand(),new ImportFileCommand()};
    var processor=新文件处理器();
    IEnumerable results=processor.Execute(进程、数据);
    

    有什么想法。

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

    这里有三种解决问题的方法。注意:我没有实现错误处理或弄乱您的
    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);
    
    IEnumerable数据=。。。;
    IEnumerable进程=。。。;
    //普林克
    var结果=数据
    .天冬酰胺()
    .Select(dataItem=>process.Aggregate(dataItem,(d,p)=>p.Execute(d)))
    .ForAll(dataItem=>import(dataItem));
    //平行,Foreach
    Parallel.Foreach(data,dataItem=>import(process.Aggregate(dataItem,(d,p)=>p.Execute(d)));
    //第三方物流
    var任务=数据
    .Select(dataItem=>Task.Run(()=>import(process.Aggregate)(dataItem,(d,p)=>p.Execute(d‘‘‘));
    等待任务。何时(任务);
    
    这是学校用的吗?只是好奇。看看我的答案:@DaveSexton:这不是学校的问题。您的答案是关于通过流读取文件。我的主要问题是如何链接命令和创建流程。我只是想知道为什么您需要命令。基本上,似乎您只需要为每个“命令”链接一个
    SelectMany
    @DaveSexton:IMHO使用SelectMany,我无法将结果从LoadFileCommand传递到AnalyzeFileCommand,从AnalyziFileCommand传递到ValidateFileCommand等,但可能我错了。从文件加载是一个异步操作。如果要使用LINQ,为什么不使用Rx并使其靠近金属?我只是不确定这些命令的用途,除非这不是一个自动化的过程?@DaveSexton是的,如果这些命令被建模为异步操作,那么Rx可能会有用。或者仍然只是一堆TPL或数据流。但对于同步命令,我不明白为什么它值得转换为Rx。命令代替直接Rx或TPL的一个有用方面是,它们是有效的数据,并且链可以动态调整。
    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);