Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.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#async/await不';不要等待_C#_Async Await - Fatal编程技术网

扩展C#async/await不';不要等待

扩展C#async/await不';不要等待,c#,async-await,C#,Async Await,扩展: 如果按顺序执行的方法也存储在列表中,如何将ExecuteParallelAsync添加到该列表中 private async Task ExecuteSequential() { List<Action> sequentialMethods = new List<Action>() { SomeMethod1, SomeMethod2, await ExecuteParallelAsync, // ?

扩展:

如果按顺序执行的方法也存储在列表中,如何将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();
    }
}
当我删除每一个异步和每一个任务时,所有的任务都将按顺序运行,这一行是关键:

Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() );
当我使用最后一句话时,一切正常


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

您可以创建一个
操作,当调用该操作时,它将启动任务并等待任务完成,如下所示:

List<Action> sequentialMethods = new List<Action>()
{
    SomeMethod1,
    SomeMethod2,
    () => ExecuteParallelAsync().Wait(),
    SomeMethod3,
    SomeMethod4
};
List sequentialMethods=新列表()
{
一些方法1,
一些方法2,
()=>ExecuteParallelAsync().Wait(),
一些方法3,
一些方法4
};

您可以创建一个
操作,当调用该操作时,它将启动任务并等待任务完成,如下所示:

List<Action> sequentialMethods = new List<Action>()
{
    SomeMethod1,
    SomeMethod2,
    () => ExecuteParallelAsync().Wait(),
    SomeMethod3,
    SomeMethod4
};
List sequentialMethods=新列表()
{
一些方法1,
一些方法2,
()=>ExecuteParallelAsync().Wait(),
一些方法3,
一些方法4
};
以下是一个版本:

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

编辑:测试 代码
My1
My2
My3
将在执行之间更改顺序,但始终在
|124;|Start
|End
以下是一个版本:

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

编辑:测试 代码
My1
My2
My3
将在执行之间更改顺序,但始终在
|开始
|结束
范围内

我再次面临最初的问题,即在ExecuteParallelAsync完成之前执行SomeMethod3

那么这不是异步编程的用例。您的要求是这是同步的

尤其如此,因为您说过
MyMethod1
/
MyMethod2
/
MyMethod3
不是异步方法。如果是的话,那将是一场灾难。但是因为它们不是,所以我看不出在这里尝试使用
async
wait
有什么价值

但不要混淆异步和并行。您似乎希望在
ExecuteParallelAsync
中调用的方法并行运行,这很好。您不需要
async
wait

例如:

private void ExecuteSequential()
{
列表顺序方法=新列表()
{
一些方法1,
一些方法2,
执行并行,
一些方法3,
一些方法4
};
for(int i=0;icurrentMethod.Invoke());
}
我再次面临最初的问题,即在ExecuteParallelAsync完成之前执行SomeMethod3

那么这不是异步编程的用例。您的要求是这是同步的

尤其如此,因为您说过
MyMethod1
/
MyMethod2
/
MyMethod3
不是异步方法。如果是的话,那将是一场灾难。但是因为它们不是,所以我看不出在这里尝试使用
async
wait
有什么价值

但不要混淆异步和并行。您似乎希望在
ExecuteParallelAsync
中调用的方法并行运行,这很好。您不需要
async
wait

例如:

private void ExecuteSequential()
{
列表顺序方法=新列表()
{
一些方法1,
一些方法2,
执行并行,
一些方法3,
一些方法4
};
for(int i=0;icurrentMethod.Invoke());
}

Await是一种语法糖,用于将方法切割成状态机。它将如何以多种方法切割列表?等待应该在调用方法时完成,不能动态生成。这是在编译时完成的。根据我的经验,
ParallelFor
不能很好地使用异步函数。这还取决于
MyMethod1
/
MyMethod2
/
MyMethod3
是如何实现的。它们是
async
方法吗?不,它们不是。它们在基类中是受纯保护的虚拟void,因此在派生类中是受保护的重写void。我唯一更改的两个方法是ExecuteSequential和ExecuteParallelAsync from(async)void to async Task。如果它们不是异步的,您不能等待它们。您可以创建一个任务来等待它,然后创建其他任务来运行非异步代码。为什么?这只会降低代码的效率,没有任何好处。只需使用一个parallel for(这基本上就是wait is语法糖)将该方法切割成一个状态机。它将如何以多种方法切割列表?等待应该在调用方法时完成,不能动态生成。这是在编译时完成的。根据我的经验,
ParallelFor
不能很好地使用异步函数。这还取决于
MyMethod1
/
MyMethod2
/
MyMethod3
是如何实现的。它们是
async
方法吗?不,它们不是。它们在基类中是受纯保护的虚拟void,因此在派生类中是受保护的重写void。我唯一更改的两个方法是ExecuteSequential和ExecuteParallelAsync from(async)void to async Task。如果它们不是异步的,您不能等待它们。您可以创建一个任务来等待它,然后创建其他任务来运行非异步代码。为什么?这只会降低代码的效率,没有任何好处。用一个平行的
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