gpt4 book ai didi

c# - LINQ 代码中的异步 - 说明?

转载 作者:可可西里 更新时间:2023-11-01 09:06:12 25 4
gpt4 key购买 nike

几乎每个 SO 关于此主题的回答都指出:

LINQ doesn't work perfectly with async

还有:

I recommend that you not think of this as "using async within LINQ"

但在 Stephen 的书中有一个示例:

Problem: You have a collection of tasks to await, and you want to do some processing on each task after it completes. However, you want to do the processing for each one as soon as it completes, not waiting for any of the other tasks.

推荐的解决方案之一是:

static async Task<int> DelayAndReturnAsync(int val)
{
await Task.Delay(TimeSpan.FromSeconds(val));
return val;
}

// This method now prints "1", "2", and "3".
static async Task ProcessTasksAsync()
{
// Create a sequence of tasks.
Task<int> taskA = DelayAndReturnAsync(2);
Task<int> taskB = DelayAndReturnAsync(3);
Task<int> taskC = DelayAndReturnAsync(1);
var tasks = new[] { taskA, taskB, taskC };
var processingTasks = tasks.Select(async t =>
{
var result = await t;
Trace.WriteLine(result);
}).ToArray();

// Await all processing to complete
await Task.WhenAll(processingTasks);

}

问题 #1:

我不明白为什么现在 async 在 LINQ 语句中起作用了。我们不是刚刚说过“不要考虑在 LINQ 中使用 async”吗?

问题 #2:

当控件到达此处的 await t 时 — 实际上发生了什么?控件是否离开 ProcessTasksAsync 方法?还是离开匿名方法并继续迭代?

最佳答案

I don't understand why now async inside a LINQ statement - does work . Didn't we just say "don't think about using async within LINQ" ?

async 大部分 不适用于 LINQ,因为 IEnumerable<T>扩展并不总是正确地推断委托(delegate)类型并遵循 Action<T> .他们对Task没有特别了解类(class)。这意味着实际的异步委托(delegate)变为 async void ,这很糟糕。在Enumerable.Select的情况下,我们有一个重载返回一个 Func<T> (在我们的例子中又是 Func<Task>),相当于 async Task ,因此它适用于异步用例。

When the control reaches the await t here — What is actually happen? Does the control leaves the ProcessTasksAsync method ?

不,它没有。 Enumerable.Select是关于投影序列中的所有元素。这意味着对于集合中的每个元素,await t这会将控制权交还给迭代器,迭代器将继续迭代所有元素。这就是为什么你以后必须 await Task.WhenAll , 以确保所有元素都已完成执行。

关于c# - LINQ 代码中的异步 - 说明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31489597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com