下面的选项 1 和选项 2 有什么区别?

    private void BGW_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i=1; i<=100; i++)
        {
            string txt = i.ToString();
            if (Test_Check.Checked)
                //OPTION 1
                Test_BackgroundWorker.ReportProgress(i, txt);
            else
                //OPTION 2
                this.BeginInvoke((Action<int, string>)UpdateGUI,
                                  new object[] {i, txt});
        }
    }

    private void BGW_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        UpdateGUI(e.ProgressPercentage, (string)e.UserState);
    }

    private void UpdateGUI(int percent, string txt)
    {
        Test_ProgressBar.Value = percent;
        Test_RichTextBox.AppendText(txt + Environment.NewLine);
    }

查看反射器, Control.BeginInvoke() 似乎使用:
this.FindMarshalingControl().MarshaledInvoke(this, method, args, 1);

似乎最终调用了一些像 PostMessage() 这样的 native 函数,无法完全弄清楚反射器的流程(讨厌的编译器转到优化)

而 BackgroundWorker.Invoke() 似乎使用:
this.asyncOperation.Post(this.progressReporter, args);

这似乎最终会调用 ThreadPool.QueueUserWorkItem()

(我只是猜测这些是每种情况的相关函数调用。)如果我理解正确,使用 ThreadPool 不能保证执行顺序,而使用 Post 机制可以。也许这会是一个潜在的差异? ( 编辑 - 我无法综合这种情况 - 在这两种情况下似乎都保留了调用顺序,至少在我的简单测试中。)

谢谢!

最佳答案

他们都是一样的。您在 BackgroundWorker 中看到的调用使用 SynchronizationContextPost() 方法的默认实现确实使用线程池,但是在启动 Windows 窗体应用程序时,默认同步上下文被 WindowsFormsSynchronizationContext 替换,它实际上调用 Control.BeginInvoke()

关于winforms - BackgroundWorker.ReportProgress() 和 Control.BeginInvoke() 的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2865971/

10-13 00:03