gpt4 book ai didi

c# - 运行任务序列,一个接一个

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

我有一系列任务,其中每个任务都取决于前一个任务的输出。我想将其表示为单个 Task 对象,其结果是序列末尾的输出。 (如果任务不相互依赖,那么我可以并行执行,我会使用 TaskFactory.ContinueWhenAll。)

我希望能够实现这个方法:

static Task<TState> AggregateAsync<T, TState>(
IEnumerable<T> items,
TState initial,
Func<TState, T, Task<TState>> makeTask);

如何高效地依次运行任务?我使用的是 C# 4.0,所以我不能使用 async/await 为我做这件事。

编辑:我可以这样写 AggregateAsync:

static Task<TState> AggregateAsync<T, TState>(IEnumerable<T> items, TState initial, Func<TState, T, Task<TState>> makeTask)
{
var initialTask = Task.Factory.StartNew(() => initial);
return items.Aggregate(
initialTask,
(prevTask, item) =>
{
prevTask.Wait(); // synchronous blocking here?
return makeTask(prevTask.Result, item);
});
}

但我肯定会得到一批任务,每个任务都会同步等待前面的任务吗?

最佳答案

简单的方法(使用 Microsoft.Bcl.Async):

static async Task<TState> AggregateAsync<T, TState>(
this IEnumerable<T> items,
TState initial,
Func<TState, T, Task<TState>> makeTask)
{
var state = initial;
foreach (var item in items)
state = await makeTask(state, item);
return state;
}

困难的方法:

static Task<TState> AggregateAsync<T, TState>(
this IEnumerable<T> items,
TState initial,
Func<TState, T, Task<TState>> makeTask)
{
var tcs = new TaskCompletionSource<TState>();
tcs.SetResult(initial);
Task<TState> ret = tcs.Task;
foreach (var item in items)
{
var localItem = item;
ret = ret.ContinueWith(t => makeTask(t.Result, localItem)).Unwrap();
}
return ret;
}

请注意,“硬”方式的错误处理更加笨拙;第一个项目的异常将被每个后续项目包装在 AggregateException 中。 “简单”的方法不会像这样包装异常。

关于c# - 运行任务序列,一个接一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20422026/

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