扩展C#异步/等待await不等待

时间:2019-10-18 08:57:03

标签: c# async-await

扩展:C# async/await await doesn't await

如果顺序执行的方法也存储在列表中,那么如何将 ExecuteParallelAsync 添加到该列表中?

XATransactions.java

说明:

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();
    }
}

sequentialMethods 列表<< em> Action > ,但 ExecuteParallelAsync 不是Action。我已尝试按照建议拆分列表。不幸的是,这无济于事。

Marc从原始代码中建议的方法工作正常。但是我想在每个(顺序)方法调用之后做一些额外的事情,这就是为什么我试图使用列表和循环而不是普通方法调用的原因。

但是,当我这样做时,我再次面对原始问题,即在ExecuteParallelAsync完成之前执行SomeMethod3。

再次, ExecuteParallelAsync 中的所有内容都可以并且应该同时执行。 ExecuteSequential 中的所有内容都必须按顺序执行。

解决方案:

加百列绝对正确。关键的声明是这样

private async Task ExecuteParallelAsync()
{
    List<Action> methods = new List<Action>()
    {
        MyMethod1,
        MyMethod2,
        MyMethod3
    };


    await Task.Run( () => { Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() ); } );            
}

当我删除每个异步和每个Task时,所有要按顺序运行的内容都将按顺序执行,这行是关键:

await Task.Run( () => { Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() ); } );

当我使用最后一条语句时,一切正常。

感谢大家,您的所有想法,思想和努力都得到了帮助,并受到赞赏。

3 个答案:

答案 0 :(得分:2)

  

我再次面对原始问题,即在ExecuteParallelAsync完成之前执行SomeMethod3

然后这不是异步编程的用例。您的要求是这是同步的。

由于您说MyMethod1 / MyMethod2 / MyMethod3不是异步方法,所以尤其如此。如果是的话,那将是totally different thing。但是由于它们不是,所以在这里尝试使用asyncawait并没有任何价值。

但是不要将异步与并行混淆。看来您希望并行运行ExecuteParallelAsync中调用的方法,这很好。您只是不需要asyncawait

例如:

private void ExecuteSequential()
{
    List<Action> sequentialMethods = new List<Action>()
    {
        SomeMethod1,
        SomeMethod2,
        ExecuteParallel,
        SomeMethod3,
        SomeMethod4
    };

    for ( int i = 0 ; i < sequentialMethods.Count ; i++ )
    {
        sequentialMethods.ElementAt( i ).Invoke();
    }
}

private void ExecuteParallel()
{
    List<Action> methods = new List<Action>()
    {
        MyMethod1,
        MyMethod2,
        MyMethod3
    };

    Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() );            
}

答案 1 :(得分:0)

您可以创建一个repeatInterval: 30, TimeUnit.MINUTES,当调用它时它将启动任务并等待其完成,如下所示:

Action

答案 2 :(得分:0)

这是一个版本:

inq

仅作记录,filter.where = {id: { inq: objectAsPerId }}; and then const transList = this.transactionRepository.find(filter); 可能只是一个标准的异步方法(在顺序执行事情方面非常好)。

private async Task  ExecuteSequential()
{
    var sequentialMethods = new List<Func<Task>>()
    {
        () => Task.Run(SomeMethod1),
        () => Task.Run(() => SomeMethod2("Hey!")), 
        ExecuteParallelAsync, 
        () => Task.Run(SomeMethod3),
        () => Task.Run(SomeMethod4)
    };

    for ( int i = 0 ; i < sequentialMethods.Count ; i++ )
    {
        Task t = sequentialMethods[i].Invoke(); 
        await t;
        // or just await sequentialMethods[i]();
    }
}

编辑:测试

代码

ExecuteSequential

输出

private async Task ExecuteSequential()
{
  SomeMethod1();
  SomeMethod2();
  await ExecuteParallelAsync(); 
  SomeMethod3();
  SomeMethod4();
};

class Program { public void MyMethod1() => Console.WriteLine("||My1"); public void MyMethod2() => Console.WriteLine("||My2"); public void MyMethod3() => Console.WriteLine("||My3"); private async Task ExecuteParallelAsync() { Console.WriteLine("||Start"); List<Action> methods = new List<Action>() { MyMethod1, MyMethod2, MyMethod3 }; await Task.Run(() => { Parallel.ForEach(methods, (currentMethod) => currentMethod.Invoke()); }); // This could be just 'currentMethod();' (no Invoke()) Console.WriteLine("||End"); } public void SomeMethod1() => Console.WriteLine("Some1"); public void SomeMethod2(string s) => Console.WriteLine($"Some2: {s}"); public void SomeMethod3() => Console.WriteLine("Some3"); public void SomeMethod4() => Console.WriteLine("Some4"); private async Task ExecuteSequential() { var sequentialMethods = new List<Func<Task>>() { () => Task.Run(SomeMethod1), () => Task.Run(() => SomeMethod2("Hey!")), ExecuteParallelAsync, () => Task.Run(SomeMethod3), () => Task.Run(SomeMethod4) }; for (int i = 0; i < sequentialMethods.Count; i++) { await sequentialMethods[i](); } } static async Task Main(string[] args) { await new Program().ExecuteSequential(); Console.WriteLine("All done"); } } Some1 Some2: Hey! ||Start ||My3 ||My2 ||My1 ||End Some3 Some4 All done My1将在两次执行之间更改顺序,但始终在My2My3之内。