使用print语句组织任务结果

时间:2013-07-10 14:45:59

标签: c# asynchronous .net-4.0 task-parallel-library task

我使用任务,BeginGetResponse,EndGetResponse和fromasync以及continuewith方法将url发送到列表中。使用Console.WriteLine是否有办法在每个网址结束时组织/安排每个网址结果?当我尝试处理这个时,打印语句不同步。

示例:

1.url:google.com     -ResponseStatus:up      - 时间      - 接收时间 2. url yahoo.com 等

1 个答案:

答案 0 :(得分:1)

如果要按特定顺序打印结果,而不是按照它们碰巧完成的顺序打印,则不要在ContinueWith调用中为每个任务添加打印语句。而是在所有任务的集合上调用WhenAll,然后向添加延续打印所有值。

public static void AddPrintStatements(IEnumerable<Task<string>> tasks)
{
    Task.WhenAll(tasks)
        .ContinueWith(t =>
        {
            foreach (var line in t.Result)
                PrintResults(line);
        });
}

由于您使用的是4.0并且没有WhenAll,因此您可以使用此代码:

public static Task<IEnumerable<T>> WhenAll<T>(IEnumerable<Task<T>> tasks)
{
    return Task.Factory.ContinueWhenAll(tasks.ToArray(),
        results => results.Select(t => t.Result));
}

如果您希望结果在进入时打印,但也保持其顺序,那么您也可以通过执行每个任务并添加前一个延续和给定任务的延续来实现:< / p>

public static void AddPrintStatements2(IEnumerable<Task<string>> tasks)
{
    Task continuation = Task.FromResult(true);

    foreach (var task in tasks)
    {
        continuation = continuation.ContinueWith(t =>
            task.ContinueWith(t2 => PrintResults(t2.Result)))
            .Unwrap();
    }
}

由于你使用4.0,你也没有FromResult,所以你可以使用它:

public static Task<T> FromResult<T>(T result)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(result);
    return tcs.Task;
}