gpt4 book ai didi

c# - 是否有默认方法来获取成功完成的第一个任务?

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

假设我有几个任务:

void Sample(IEnumerable<int> someInts)
{
var taskList = someInts.Select(x => DownloadSomeString(x));
}

async Task<string> DownloadSomeString(int x) {...}

我想获得第一个成功任务的结果。因此,基本的解决方案是编写如下内容:

var taskList = someInts.Select(x => DownloadSomeString(x));
string content = string.Empty;
Task<string> firstOne = null;
while (string.IsNullOrWhiteSpace(content)){
try
{
firstOne = await Task.WhenAny(taskList);
if (firstOne.Status != TaskStatus.RanToCompletion)
{
taskList = taskList.Where(x => x != firstOne);
continue;
}
content = await firstOne;
}
catch(...){taskList = taskList.Where(x => x != firstOne);}
}

但是这个解决方案似乎运行了 N+(N-1)+..+K 任务。其中 NsomeInts.CountK 是任务中第一个成功任务的位置,因此它重新运行所有任务,除了被捕获的任务什么时候。那么,有什么方法可以通过运行最多 N 任务来获得成功完成的第一个任务? (如果成功任务将是最后一个)

最佳答案

您需要做的就是创建一个 TaskCompletionSource,为您的每个任务添加一个延续,并在第一个任务成功完成时设置它:

public static Task<T> FirstSuccessfulTask<T>(IEnumerable<Task<T>> tasks)
{
var taskList = tasks.ToList();
var tcs = new TaskCompletionSource<T>();
int remainingTasks = taskList.Count;
foreach (var task in taskList)
{
task.ContinueWith(t =>
{
if (task.Status == TaskStatus.RanToCompletion)
tcs.TrySetResult(t.Result);
else
if (Interlocked.Decrement(ref remainingTasks) == 0)
tcs.SetException(new AggregateException(tasks.SelectMany(t1 => t1.Exception.InnerExceptions)));
});
}
return tcs.Task;
}

还有一个没有结果的任务版本:

public static Task FirstSuccessfulTask(IEnumerable<Task> tasks)
{
var taskList = tasks.ToList();

var tcs = new TaskCompletionSource<bool>();

int remainingTasks = taskList.Count;

foreach (var task in taskList)
{
task.ContinueWith(t =>
{
if (task.Status == TaskStatus.RanToCompletion)
tcs.TrySetResult(true);
else
if (Interlocked.Decrement(ref remainingTasks) == 0)
tcs.SetException(new AggregateException(
tasks.SelectMany(t1 => t1.Exception.InnerExceptions)));
});
}

return tcs.Task;
}

关于c# - 是否有默认方法来获取成功完成的第一个任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37528738/

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