在 WinForms 上使用 TPL 进行并行编程

2024-01-01

我尝试在 WinForms .NET 4.0 上使用 TPL,我遵循this http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx步骤(转到文章末尾)适用于 WPF 并做了一些小更改,以便它可以在 WinForms 上工作,但它仍然不起作用..它应该在标签和 richTextBox 上显示结果,但它不是...我认为并行进程工作导致当我单击按钮时鼠标开始缓慢移动一段时间。

public static double SumRootN(int root)
{   double result = 0;
    for (int i = 1; i < 10000000; i++)
    {   result += Math.Exp(Math.Log(i) / root);}
    return result;
}
private void button1_Click(object sender, EventArgs e)
{   richTextBox1.Text = "";
    label1.Text = "Milliseconds: ";
    var watch = Stopwatch.StartNew();
    List<Task> tasks = new List<Task>();
    for (int i = 2; i < 20; i++)
    {   int j = i;
        var t = Task.Factory.StartNew
          (   () =>
                {   var result = SumRootN(j);
                    Dispatcher.CurrentDispatcher.BeginInvoke
                        (new Action
                             (   () => richTextBox1.Text += "root " + j.ToString() 
                                   + " " + result.ToString() + Environment.NewLine
                             )
                         , null
                        );
                 }
            );
        tasks.Add(t);
    }
    Task.Factory.ContinueWhenAll
         (  tasks.ToArray()
            , result =>
                {   var time = watch.ElapsedMilliseconds;
                    Dispatcher.CurrentDispatcher.BeginInvoke
                          (   new Action
                                (    () =>
                                      label1.Text += time.ToString()
                                 )
                           );
                }
        );
}

暂且不说这样做好不好,从学习的角度以及评论中提到的主题“System.Windows.Threading.Dispatcher 和 WinForms?”和有点令人困惑的答案 https://stackoverflow.com/a/1160035/200449:

“如果您确定处于 UI 线程中(例如,在按钮中。单击处理程序), Dispatcher.CurrentDispatcher 为您提供了 UI 线程调度程序 您可以像平常一样从后台线程分派到 UI 线程”

值得一提的是(也提供了我的答案 https://stackoverflow.com/a/16007664/200449对于上述问题):

  • Task.Factory.StartNew()在不同于主 UI 或其子线程的多个线程上生成执行
  • 可以使用调度员 http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher%28v=vs.100%29.aspx在任何线程上
  • WPF 应用程序 OOTB(开箱即用)提供System.Windows.Threading.Dispatcher DispatcherObject.Dispatcher http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherobject%28v=vs.100%29.aspx如果 Windows 窗体中缺少 UI 线程
  • 有问题时使用Dispatcher.CurrentDispatcher正在获取由非 ui 线程任务生成的调度程序

无论如何,从教学的角度来看对原始 WPF 代码进行最少的更改,你应该已经捕获并使用了 UI 调度程序:

private void button1_Click(object sender, EventArgs e)
{   Dispatcher dispatcherUI = Dispatcher.CurrentDispatcher;//added **********
    richTextBox1.Text = "";
    label1.Text = "Milliseconds: ";
    var watch = Stopwatch.StartNew();
    List<Task> tasks = new List<Task>();
    for (int i = 2; i < 20; i++)
    {   int j = i;
        var t = Task.Factory.StartNew
          (   () =>
                {   var result = SumRootN(j);
      //Dispatcher.CurrentDispatcher.BeginInvoke//***changed to
                    dispatcherUI.BeginInvoke
                        (new Action
                             (   () => richTextBox1.Text += "root " + j.ToString() 
                                   + " " + result.ToString() + Environment.NewLine
                             )
                         , null
                        );
                 }
            );
        tasks.Add(t);
    }
    Task.Factory.ContinueWhenAll
         (  tasks.ToArray()
            , result =>
                {   var time = watch.ElapsedMilliseconds;
     //Dispatcher.CurrentDispatcher.BeginInvoke//**************changed to
                    dispatcherUI.BeginInvoke//added
                          (   new Action
                                (    () =>
                                      label1.Text += time.ToString()
                                 )
                           );
                }
        );
} 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 WinForms 上使用 TPL 进行并行编程 的相关文章

随机推荐