需要依次运行等待的子任务(在控制台应用程序中)的并行处理]]

问题描述 投票:0回答:1

[我试图找到处理项目并发处理的最佳方法,该项目由需要顺序执行的各个子任务组成(C#/ .net 4.6)

即同时处理列表中的对象,但是按顺序执行一系列(等待异步)子任务-并且仅在所有操作完成后才运行代码。

伪代码:

public async Task SynchronizeItems() 
{
   List<Items> items = await client.RetrieveItems();
   foreach (var item in collection) // but in parallel
   {
      await item.DoThingA()
      await item.DoThingB()
      await item.DoThingC()
   }   
   // **only run code here when all sub tasks for all items are complete**
}

更大的上下文(以简化形式):我有一个可执行文件,需要每N分钟作为计划任务运行。 Program的入口点/ Main方法将初始化ItemSyncService并调用SynchronizeItems()。因为SynchronizeItems()是异步的,所以当控件返回到Main方法时,遇到第一次等待时,整个过程将立即退出。

(仅添加调用SynchronizeItems()。Wait()不起作用,因为这是一种简化的情况。实际上,调用层次结构确实很复杂,其中程序集是动态加载的,调用的方法等,等等)] >

为了防止这种情况(基于我在Stack Overflow上看到的帖子,我添加了ManualResetEvent,以便可以手动控制“所有任务完成”的时间。

static void Main(string[] args)
{
   ManualResetEvent completionEvent = new ManualResetEvent(false);
   _executor = new ItemService();
   _executor.SynchronizeItems(completionEvent)

   // wait for completion events to be set before exiting the method
   completionEvent.WaitOne()
}

然后,同步方法如下所示:

public async Task SynchronizeItems(ManualResetEvent completionEvent) 
{
   List<Items> items = await client.RetrieveItems();
   foreach (var item in collection) // but in parallel
   {
      await item.DoThingA()
      await item.DoThingB()
      await item.DoThingC()
   }   
   // ** only run code here when all sub tasks for all items are complete**
   // signal completion
   completionEvent.Set()
}

更改此项以将并行ForEach用于项目级并发看起来像这样:

public async Task SynchronizeItems(ManualResetEvent completionEvent) 
{
   List<Items> items = await client.RetrieveItems();
   Parallel.ForEach(items, async (item) => // in parallel now
   {
      await item.DoThingA()
      await item.DoThingB()
      await item.DoThingC()
   }   
   **// only run code here when all sub tasks for all items are complete **
   // signal completion
   completionEvent.Set() // ** this now runs immediately without waiting **
}

但是,完成此操作后,将为每个项目启动任务后立即调用completionEvent。

我发现了一个实现ParallelForEachAsync(https://github.com/Dasync/AsyncEnumerable)的第三方库。看来这将阻止在所有项目的所有等待任务完成之前设置完成事件。

但是我想知道我是否会错误地进行此操作?最初,当我写这篇文章时,我是作为控制台应用程序进行测试的,并且在交互模式下具有ReadKey(),因此我没有遇到与异步相关的进程退出问题。

[我试图找到处理项目并发处理的最佳方法,该项目由需要依次执行的各个子任务组成(C#/ .net 4.6),即...中的处理对象,

c# asynchronous async-await task-parallel-library
1个回答
1
投票

如果DoThings方法正在发出I / O请求而不是CPU绑定操作,则可以将项目处理移至其自己的方法:

private async Task ProcessItem(Items item) {
    await item.DoThingA();
    await item.DoThingB();
    await item.DoThingC();
}
© www.soinside.com 2019 - 2024. All rights reserved.