【问题标题】:task parallel library + winforms progress bar任务并行库+winforms进度条
【发布时间】:2011-02-22 09:02:43
【问题描述】:

我想使用来自任务的委托来更新 winforms 中的进度条。

 scheduler = TaskScheduler.FromCurrentSynchronizationContext();
        public delegate void NotifyAboutIterationEnd(int iteration);
        public event NotifyAboutIterationEnd Notify;
          var task = Task.Factory.StartNew(() =>
           {
        //...
                   Task.Factory.StartNew(() =>
                   {
                       Notify(++index);
               }, CancellationToken.None, TaskCreationOptions.None, scheduler);
    //...

当我启动这段代码时,我可以命中的最后一个断点在 Notify(++index); 行。 然后程序冻结并结束。 如果我将调度程序更改为例如调度程序 = TaskScheduler.Current;然后我有一个例外,不能从其他线程修改 gui。这意味着委托/事件工作正常。那么为什么它在第一种情况下不起作用呢?

【问题讨论】:

    标签: winforms progress-bar task-parallel-library


    【解决方案1】:

    发生这种情况是因为 Task.Factory.StartNew() 实际上并没有开始一个新任务,而是 SCEDULE 它。即使在您的主要任务完成后,默认调度程序也可以启动它们。记住任务!=线程。 Thread.Start - 总是立即启动线程,Task.Factory.StartNew 或 Task.Start 仅调度。您可以在 Task.Factory.StartNew() 之后使用 .Wait()。这将导致等待进度条被更新。 但是,我确信这不是最好的解决方案。解决方案 如果您的计算花费大量时间,我真的建议您使用 Task.Factory.Startnew 和 TaskCreationOptions.LongRunning 和 Notify.BeginInvoke 用于更新进度条。当然,notify 事件的处理程序必须根据 Winforms Updating UI Asynchronously Pattern 正确实现。 你可以在Winforms Updating UI Asynchronously Pattern - Need to Generalize看到一个例子 希望这会有所帮助!

    很好地缺乏并行性;)。

    【讨论】:

      【解决方案2】:

      你可以这样做

               ProgressBar pb = new ProgressBar();   
               pb.Maximum = 100;   
               pb.Dock = DockStyle.Fill;   
               Controls.Add(pb); 
      
               int i = 0, flag = 5;
                  var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                  Task.Factory.StartNew(() =>
                  {
                      while (i <= 100
                      {
                          Task.Factory.StartNew(() =>
                          {
                              pb.Value++;
                          }, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
                          System.Threading.Thread.SpinWait(50000000); // do work here   
                  i++
      
                      }
                  });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-02
        • 1970-01-01
        • 2020-10-23
        相关资源
        最近更新 更多