【问题标题】:Organizing task results using print statements使用打印语句组织任务结果
【发布时间】:2013-07-10 14:45:59
【问题描述】:

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

例子:

1.url:google.com -响应状态:向上 -发送时间 -接收时间 2. 网址 yahoo.com 等等

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 好的,所以在我的代码中我有一个 HttpWebRequest myReq Task task = Task.Factory.FromAsync(myReq.BeginGetResponse, myReq.EndGetResponse, null); task.ContinueWith(t => { //打印语句 });如果在 continueWith 中调用了我的 print 语句,我应该将您讨论的那些方法放在哪里?
    • @DeVonte 然后在将任务传递给此方法之前使用适当的延续,或者根据您的任务实际返回的内容修改这些方法。
    • 好的,所以在我的代码中我有一个 HttpWebRequest myReq Task task = Task.Factory.FromAsync(myReq.BeginGetResponse, myReq.EndGetResponse, null); task.ContinueWith(t => { //打印语句 });如果在 continueWith 中调用了我的 print 语句,我应该将您讨论的那些方法放在哪里?
    • @DeVonte 你把从FromAsync 创建的任务放到一个集合中,比如List。然后将它们传递给这个方法。此方法有一个 PrintResults 方法,您可以定义它来进行打印。
    • 好的,我看看我能做什么
    最近更新 更多