支持.NET 4.0"任务并行库"中的进度报告和增量结果

Hem*_*ant 15 c# .net-4.0 task-parallel-library

我知道任务并行库仍然处于测试阶段,可能会有更少的可用资源,但是从我读过的内容来看,库为任务调度,异常处理取消提供了非常特殊的处理.

但我没有找到任何关于进度报告和从任务发送增量结果的引用.这两件事似乎太重要了,不容忽视.您能否介绍如何在任务并行库中处理这些内容或参考一些解释它们的文章?

Rob*_*vey 9

此示例更新进度条:

using System;   
using System.Threading;   
using System.Threading.Tasks;   
using System.Windows.Forms;   

class SimpleProgressBar : Form   
{   
    [STAThread]   
    static void Main(string[] args)   
    {   
        Application.EnableVisualStyles();   
        Application.Run(new SimpleProgressBar());   
    }   

    protected override void OnLoad(EventArgs e)   
    {   
        base.OnLoad(e);   

        int iterations = 100;   

        ProgressBar pb = new ProgressBar();   
        pb.Maximum = iterations;   
        pb.Dock = DockStyle.Fill;   
        Controls.Add(pb);   

        Task.ContinueWith(delegate   
        {   
            Parallel.For(0, iterations, i =>  
            {   
                Thread.SpinWait(50000000); // do work here   
                BeginInvoke((Action)delegate { pb.Value++; });   
            });   
        });   
    }   
}  
Run Code Online (Sandbox Code Playgroud)

从Parallel.For内部更新进度条


Cal*_*aNN 8

这是我最热门的搜索结果之一,仍然没有在Task Parallel Library这里取得进展的例子......

今天我刚遇到TPL,因为我想开发新的多线程应用程序,但没有使用BackgroundWorker(因为我以前用好的代码读过任务的任务)

我从@Stephen Cleary回答编译示例,他的链接相当复杂,以寻找进展,以及其他一些网站.

这是如何使用UI线程安全方式执行ProgressCompleted的非常简单的示例:

        TaskScheduler currentTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        Task<string>.Factory.StartNew(() =>
        {
            // loop for about 10s with 10ms step
            for (int i = 0; i < 1000; i++)
            {
                Thread.Sleep(10);
                Task.Factory.StartNew(() =>
                {
                    // this is a task created each time you want to update to the UI thread.
                    this.Text = i.ToString();
                }, CancellationToken.None, TaskCreationOptions.None, currentTaskScheduler);
            }
            return "Finished!";
        })
        .ContinueWith(t =>
        {
            // this is a new task will be run after the main task complete!
            this.Text += " " + t.Result;
        }, currentTaskScheduler);
Run Code Online (Sandbox Code Playgroud)

代码将在10秒内显示1到1000,然后附加"完成!" 窗体中的字符串形式标题栏.您可以看到TaskScheduler是创建UI线程安全更新的棘手方法,因为我认为任务计划在主线程上运行.


Ste*_*ary 7

没有像BackgroundWorker那样的内置支持.

您可以直接使用SynchronizationContext; 这里有一个很棒的视频:http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch? video = TasksAndThreadAffinity.wmv

作者在此视频中开发了两个解决方案:一个使用SynchronizationContext,另一个使用Task Continuations.对于您的问题,continuation将不起作用,但SynchronizationContext方法将正常工作.

PS如果您正在创建可重用的代码,那么当您捕获SynchronizationContext.Current时,您应该测试null并且(如果它为null)使用默认构造的SynchronizationContext.

更新:我在我的博客上发布了此代码.我的解决方案实际上是基于Task一个TaskScheduler使用SynchronizationContext底层调度回到UI线程的解决方案.与接受的答案不同,此解决方案适用于WPF和Windows窗体.