c# - 链接任务的正确方法

标签 c# multithreading task-parallel-library

我想链接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/

相关文章:

java - 由于集群时可能出现的问题,Servlet 不应启动线程....什么问题?

c# - 调用 Azure ActiveDirectory 时的任务状态 WaitingForActivation

c# - 如何在 .net 4.0 中获取正在运行的任务列表

c - 如何将字符串数组中的元素传递给线程?

Java 线程与对象

c# - 我如何知道任务是因超时还是手动触发而取消?

c# - 在 C# 中运行命令并等待完成

c# - Blazor - 参数值的组件 "intellisense"

c# - 强制执行特定数量的参数

c# - .Net Core 1.1 上的 OData v4 缺失/$元数据