gpt4 book ai didi

c# - 如何将其他上下文信息与任务一起传递给 Task.WhenAll?

转载 作者:行者123 更新时间:2023-12-05 02:40:57 27 4
gpt4 key购买 nike

考虑以下理想代码(它不起作用)。我实际上是在尝试创建 Task 的列表返回特定对象的 s,将它们与 string 相关联标识符,然后使用 Task.WhenAll 批量执行所有这些.在执行结束时,我需要得到那些 Task结果 s 仍然与它们最初创建时使用的字符串标识符相关联:

public async Task<SomeObject> DoSomethingAsync(string thing)
{
// implementation elided
}

public async Task<SomeObject> DoSomethingElseAsync(string thing)
{
// different implementation elided
}

public async Task<IEnumerable<(string, SomeObject)>>
DoManyThingsAsync(IEnumerable<string> someListOfStrings, bool condition)
{
var tasks = new List<(string, Task<SomeObject>)>();

foreach (var item in someListOfStrings)
{
if (condition)
{
tasks.Add((item, DoSomethingAsync(item)));
}
else
{
tasks.Add((item, DoSomethingElseAsync(item)));
}
}

// this doesn't compile, i'm just demonstrating what i want to achieve
var results = await Task.WhenAll(tasks);

return results;
}

这可以重写为:

public async Task<(string, SomeObject)> DoSomethingWrapperAsync(string thing)
=> (thing, await DoSomethingAsync(thing));

public async Task<(string, SomeObject)> DoSomethingElseWrapperAsync(string thing)
=> (thing, await DoSomethingElseAsync(thing));

public async Task<IEnumerable<(string, SomeObject)>>
DoManyThingsAsync(IEnumerable<string> someListOfStrings, bool condition)
{
var tasks = new List<Task<(string, SomeObject)>>();

foreach (var thing in someListOfStrings)
{
if (condition)
{
tasks.Add(DoSomethingWrapperAsync(thing));
}
else
{
tasks.Add(DoSomethingElseWrapperAsync(thing));
}
}

// this does compile
var results = await Task.WhenAll(tasks);

return results;
}

问题是我需要为我将要调用的每个可能的离散异步函数提供一个额外的包装器方法,这感觉是不必要和浪费的,而且代码很多(因为会有很多这样的方法)。有没有更简单的方法来实现我的需要?

我研究了可等待/等待模式的实现,但看不出如何让它与 Task.WhenAll 一起工作这需要 Task 的集合或 Task<TResult> , 因为 the guidance seems to be "don't extend those classes" .

最佳答案

您可以边走边做压缩:

public async Task<IEnumerable<(string, SomeObject)>>
DoManyThingsAsync(IEnumerable<string> someListOfStrings, bool condition)
{
var tasks = someListOfStrings
.Select(async item =>
condition ?
(item, await DoSomethingAsync(item)) :
(item, await DoSomethingElseAsync(item)))
.ToList();
return await Task.WhenAll(tasks);
}

或者,您可以将输入保存为一个单独的集合,稍后将其压缩:

public async Task<IEnumerable<(string, SomeObject)>>
DoManyThingsAsync(IEnumerable<string> someListOfStrings, bool condition)
{
// Reify input so we don't enumerate twice.
var input = someListOfStrings.ToList();

var tasks = input
.Select(item =>
condition ?
DoSomethingAsync(item) :
DoSomethingElseAsync(item))
.ToList();
var taskResults = await Task.WhenAll(tasks);

return input.Zip(taskResults, (item, taskResult) => ((item, taskResult)));
}

关于c# - 如何将其他上下文信息与任务一起传递给 Task.WhenAll?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68362060/

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