【发布时间】:2019-10-19 04:40:16
【问题描述】:
扩展:C# async/await await doesn't await
如果顺序执行的方法也存储在列表中,我如何将 ExecuteParallelAsync 添加到该列表中?
private async Task ExecuteSequential()
{
List<Action> sequentialMethods = new List<Action>()
{
SomeMethod1,
SomeMethod2,
await ExecuteParallelAsync, // ???
SomeMethod3,
SomeMethod4
};
for ( int i = 0 ; i < sequentialMethods.Count ; i++ )
{
sequentialMethods.ElementAt( i ).Invoke();
}
}
澄清:
private async Task ExecuteParallelAsync()
{
List<Action> methods = new List<Action>()
{
MyMethod1,
MyMethod2,
MyMethod3
};
await Task.Run( () => { Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() ); } );
}
sequentialMethods 是 ListAction> 但 ExecuteParallelAsync 不是 Action。我已经尝试拆分列表,就像建议的那样。不幸的是,它没有帮助。
Marc 从原始代码中建议的方式可以正常工作。但是我想在每次(顺序)方法调用之后做一些额外的事情,这就是我尝试使用列表和循环而不是普通方法调用的原因。
但是当我这样做时,我又遇到了原来的问题,即 SomeMethod3 在 ExecuteParallelAsync 完成之前执行。
再次重申,ExecuteParallelAsync 中的所有内容都可以并且应该同时执行。 ExecuteSequential 中的所有内容都必须按顺序执行。
解决方案:
加布里埃尔是绝对正确的。关键的声明是这个
await Task.Run( () => { Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() ); } );
当我删除每个异步和每个任务时,以便按顺序执行所有内容,这一行是关键:
Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() );
当我使用最后一条语句时,一切正常。
感谢大家,您的所有想法、想法和努力都得到了帮助和赞赏。
【问题讨论】:
-
Await 是将方法切割成状态机的语法糖。它如何在多种方法中删除列表? await 应该在调用方法时完成,不能动态生成。这是在编译时完成的。
-
根据我的经验,
ParallelFor不能很好地处理异步函数。 -
这也取决于
MyMethod1/MyMethod2/MyMethod3是如何实现的。它们是async方法吗? -
不,他们不是。它们在基类中是普通的 protected virtual void,因此在派生类中是 protected override void。我更改的唯一两种方法是从 (async) void 到 async Task 的 ExecuteSequential 和 ExecuteParallelAsync。
-
如果它们不是异步的,你不能等待它们。您创建一个任务,等待它,然后创建其他任务来运行非异步代码。为什么?这只是使您的代码效率降低,没有任何好处。只需对
使用平行线(基本上就是 Gabirel has said)
标签: c# async-await