首页 > 解决方案 > 如何为 Task.WhenAll 捆绑异步任务?

问题描述

我并行启动了一些异步任务,如下例所示:

var BooksTask = _client.GetBooks(clientId);
var ExtrasTask = _client.GetBooksExtras(clientId);
var InvoicesTask = _client.GetBooksInvoice(clientId);
var ReceiptsTask = _client.GetBooksRecceipts(clientId);

await Task.WhenAll(
    BooksTask,
    ExtrasTask,
    InvoicesTask,
    ReceiptsTask
);

model.Books = BooksTask.Result; 
model.Extras = ExtrasTask.Result; 
model.Invoices = InvoicesTask.Result; 
model.Receipts = ReceiptsTask.Result; 

这会导致大量的打字。我在 .Net Framework 中搜索了一种缩短它的方法。我想它是lile这个。我打电话给班级Collector,因为我不知道如何命名这个概念。

var collector = new Collector();

collector.Bind(_client.GetBooks(clientId), out model.Books);

collector.Bind(_client.GetBooksExtras(clientId), out model.Extras);

collector.Bind(_client.GetBooksInvoice(clientId), out model.Invoices);

collector.Bind(_client.GetBooksRecceipts(clientId), out model.Receipts);

collector.Run();

这是一种有效的方法吗?有没有类似的东西?

标签: c#.netasync-await

解决方案


就个人而言,我更喜欢问题中的代码(但出于代码可维护性的原因使用await而不是)。Resultandyb952 的回答中所述,Task.WhenAll不需要。出于可读性的原因,我确实更喜欢它;它使语义明确,IMO 使代码更易于阅读。

我在 .Net Framework 中搜索了一种缩短它的方法。

没有任何内置的东西,也没有(据我所知)任何库。我考虑过使用元组编写一个。对于您的代码,它看起来像这样:

public static class TaskHelpers
{
    public static async Task<(T1, T2, T3, T4)> WhenAll<T1, T2, T3, T4>(Task<T1> task1, Task<T2> task2, Task<T3> task3, Task<T4> task4)
    {
        await Task.WhenAll(task1, task2, task3, task4).ConfigureAwait(false);
        return (await task1, await task2, await task3, await task4);
    }
}

有了这个帮助程序,您的原始代码将简化为:

(model.Books, model.Extras, model.Invoices, model.Receipts) = await TaskHelpers.WhenAll(
    _client.GetBooks(clientId),
    _client.GetBooksExtras(clientId),
    _client.GetBooksInvoice(clientId),
    _client.GetBooksRecceipts(clientId)
);

但它真的更具可读性吗?到目前为止,我还没有足够的信心把它变成一个图书馆。


推荐阅读