0

我正在使用任务、BeginGetResponse、EndGetResponse 和 fromasync 以及 continuewith 方法发送列表中的 URL。使用 Console.WriteLine 是否有办法在每个 url 结果返回时组织/安排它们?当我尝试处理此问题时,打印语句不同步。

例子:

1.url:google.com -ResponseStatus: up -Sent time -Received Time 2. url yahoo.com 等

4

1 回答 1

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));
}

如果您希望在结果进入时打印结果,同时保持它们的顺序,那么您也可以通过遍历每个任务并添加一个既是前一个延续又是给定任务的延续来做到这一点:

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;
}
于 2013-07-10T14:48:18.240 回答