我想链接Task
,然后并行启动链。
这段代码只是为了说明我的问题:
var taskOrig = new Task(() => { });
var task = taskOrig;
foreach (var msg in messages)
{
task=task.ContinueWith(t => Console.WriteLine(msg));
}
taskOrig.Start();
一切正常,除了我内心的小完美主义者不喜欢先执行空方法 () => { }
。
有什么办法可以避免吗?
我明白它几乎不会影响性能(除非你经常这样做),但仍然如此。在我的案例中,性能很重要,因此检查任务是否存在于每次迭代中并不是解决问题的方法。
最佳答案
你可以这样做:
Task task = Task.FromResult<object>(null);
foreach (var msg in messages)
{
task = task.ContinueWith(t => Console.WriteLine(msg));
}
以前的解决方案在 4.0 中不起作用。在 4.0 中,您需要执行以下操作:
var tcs = new TaskCompletionSource<object>();
Task task = tcs.Task;
foreach (var msg in messages)
{
task = task.ContinueWith(t => Console.WriteLine(msg));
}
tcs.SetResult(null);
(如果您愿意,可以将 SetResult
移动到 foreach 循环之前。)
从技术上讲,这与继续添加更多内容时开始执行的延续不同。不过这不太可能成为问题。
另一种选择是使用这样的东西:
public static Task ForEachAsync<T>(IEnumerable<T> items, Action<T> action)
{
return Task.Factory.StartNew(() =>
{
foreach (T item in items)
{
action(item);
}
});
}
一个示例用法是:
ForEachAsync(messages, msg => Console.WriteLine(msg));
关于c# - 链接任务的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13569091/