gpt4 book ai didi

c# - await Task.WhenAll vs ..select(async .. => await)

转载 作者:太空狗 更新时间:2023-10-29 20:12:37 25 4
gpt4 key购买 nike

只是一个简短的问题。我们这里有些误会。

我们有:

var tasks = files.Select(async fileName => await IngestFileAsync(container, fileName));
var results = await Task.WhenAll(tasks);

我说第一行仍然是并发的,但我的同事不这么认为。此外,他说第二个 await 没有任何意义,因为所有 Action 已经执行。

这段代码是否相同:

var tasks = files.Select(fileName => IngestFileAsync(container, fileName));
var results = await Task.WhenAll(tasks);

作为:

var tasks = files.Select(async fileName => await IngestFileAsync(container, fileName));
var results = Task.WhenAll(tasks);

有人可以对此有所启发吗?

干杯。

补充说:好的,所以它将并发运行。

但是,有人可以添加一些额外的信息来说明这些代码片段之间的区别吗: https://dotnetfiddle.net/lzv2B7 https://dotnetfiddle.net/dMusus

(注意第 16 行,asyncawait)。这两个之间有什么区别吗?我期望的是 with async 和 await 它会直接启动,而没有它会在涉及到 Await Task.WhenAll(tasks);

为清楚起见添加-这是我的代码-:

   private async Task<Result> IngestFilesAsync(ICloudBlobContainer container, IEnumerable<string> files)
{
_logger.LogDebug("Start IngestFilesAsync");

var tasks = files.Select(fileName => IngestFileAsync(container, fileName));
var results = await Task.WhenAll(tasks);

_logger.LogDebug("All tasks completed");

if (results.Any(t => t.IsFailure))
{
return Result.Fail(string.Join(",", results.Select(f => f.Error)));
}

return Result.Ok();
}

private async Task<Result> IngestFileAsync(ICloudBlobContainer container, string fileName)
{
_logger.LogDebug("Start IngestFileAsync");
var blob = container.GetBlockBlobReference(fileName);

_logger.LogDebug("Blob retrieved");

if (await blob.ExistsAsync())
{
using (var memoryStream = new MemoryStream())
{
_logger.LogDebug("Start download to stream");
await blob.DownloadToStreamAsync(memoryStream);
_logger.LogDebug("To mem downloaded");

_logger.LogDebug("Start ftp-upload");

return await _targetFTP.UploadAsync(memoryStream, fileName);
}
}

_logger.LogWarning("Blob does not exists");

return Result.Fail($"Blob '{fileName}' does not exist");
}

其中 _targetFTP.UploadAsync(memoryStream, fileName); 又是一个任务等等。

最佳答案

async x => await f() 创建一个返回任务的匿名函数。该任务有效地包装了由 f 创建的任务:它将在之后直接完成。特别是,这个匿名函数会尽快返回正在进行的任务。

.Select 的行为不会因枚举类型是否为任务之一而有所不同。当第一个返回的任务仍在进行中时,它允许直接获取下一个结果。

代码片段并非 100% 相同,但您所询问的差异并不存在。

差异很小;最明显的变化可能是异常处理。假设您有两个尚未实现的功能:

Task Sync() => throw new NotImplementedException();
async Task Async() => throw new NotImplementedException();

这里,var task = Sync(); 显然立即失败了。但是 var task = Async(); 不同:它成功了。这里的 async 关键字强制创建一个任务,它捕获抛出的异常。

同样的区别也适用于 .Select(x => Sync()).Select(async x => await Sync())

关于c# - await Task.WhenAll vs ..select(async .. => await),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46462839/

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