如何将异步方法放入列表中并迭代调用它们?

Ter*_*nce 3 c# arraylist task async-await

最近我想对服务调用列表实施健康检查。它们都是异步任务(例如Task<IHttpOperationResponse<XXX_Model>> method_name(...)

我想将它们全部放入一个列表中。我遵循了这篇文章的答案:Storing a list ofmethods in C#但是,它们是异步方法。

我是这样说的:异步方法的集合

List<Action> _functions = new List<Action> {
      () => accountDetailsServiceProvider.GetEmployer(EmployerId),                                  
      () => accountServiceProvider.GetAccountStatus(EmployerId)
}
Run Code Online (Sandbox Code Playgroud)

有人可以指导我正确的方法来实现将异步方法放入列表中并迭代调用它们吗?

提前致谢!

Joh*_* Wu 5

首先,您需要使方法异步。这意味着他们必须返回一个任务。例如:

public static async Task Foo()
{
    await Task.Delay(1);
    Console.WriteLine("Foo!");
}

public static async Task Bar()
{
    await Task.Delay(1);
    Console.WriteLine("Bar!");
}
Run Code Online (Sandbox Code Playgroud)

然后要将它们放入列表中,您必须将列表定义为包含正确的类型。由于异步方法实际上返回一些内容,因此它是一个 Func,而不是一个操作。它返回一个任务。

var actions = new List<Func<Task>>
{
    Foo, Bar
};
Run Code Online (Sandbox Code Playgroud)

要调用它们,请在列表中选择(使用 Linq)来调用它们。这将创建一个任务列表来代替函数列表。

var tasks = actions.Select( x => x() );
Run Code Online (Sandbox Code Playgroud)

然后就等待他们:

await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)

完整示例:

public static async Task MainAsync()
{
    var actions = new List<Func<Task>>
    {
        Foo, Bar
    };
    var tasks = actions.Select( x => x() );
    await Task.WhenAll(tasks);
}
Run Code Online (Sandbox Code Playgroud)

输出:

Foo!
Bar!
Run Code Online (Sandbox Code Playgroud)

DotNetFiddle 上的示例

如果您的方法返回布尔值,则返回类型将变为Task<bool>,其余部分也将如此:

public static async Task<bool> Foo()
{
    await Task.Delay(1);
    Console.WriteLine("Foo!");
    return true;
}

public static async Task<bool> Bar()
{
    await Task.Delay(1);
    Console.WriteLine("Bar!");
    return true;
}

var actions = new List<Func<Task<bool>>>
{
    Foo, Bar
};

var tasks = actions.Select( x => x() );

await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)

等待任务完成后,您可以使用另外一个 LINQ 语句将任务转换为其结果:

List<bool> results = tasks.Select( task => task.Result ).ToList();
Run Code Online (Sandbox Code Playgroud)