Task.WhenAll 与 LINQ select

us0*_*075 2 c# task-parallel-library

long[] orderIds={10,11,12,13};

var orders= new List<Order>();

await Task.WhenAll(orderIds.Select(async (orderId) =>
{
    var orderDetails = await GetOrderDetails(orderId);

    if (orderDetails != null)
        orders.Add(orderDetails);
}));
Run Code Online (Sandbox Code Playgroud)

我遇到了一些错误的行为,部署此代码以使其工作正常后,但在本地有时会添加所有订单,但有时会错过一些订单。

任何人都可以帮忙缩短这个,不知道我错过了什么。

Joh*_* Wu 5

ToList()首先,我建议在将任务发送到任何地方之前强制枚举任务(例如额外的调用)。您不希望意外地多次枚举该列表。

var tasks = orderIds.Select( orderId => GetOrderDetails(orderId) ).ToList();
Run Code Online (Sandbox Code Playgroud)

然后等待任务:

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

瞧,您的订单已经准备好了。

var orders = tasks.Select( t => t.Result ).Where( o => o != null ).ToList();
Run Code Online (Sandbox Code Playgroud)

顺便说一句,没有任何东西被改变,所以你是完全线程安全的,不需要任何锁(假设GetOrderDetails是线程安全的)。这是使用 linq 的函数式方法的优点之一。