以下选项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(),但无法准确地计算出来自反射器的流(烦人的编译器转到优化)。
而BackgroundWorker.Invoke()似乎使用:
this.asyncOperation.Post(this.progressReporter, args);
它似乎最终调用了ThreadPool.QueueUserWorkItem()
(我只是猜测这是每个案例的相关函数调用。)如果我正确理解,使用ThreadPool并不能保证执行顺序,而使用Post机制则会保证执行顺序。也许这是一个潜在的区别?(编辑--我无法综合这样的情况--至少在我的简单测试中,这两种情况下调用顺序似乎都保持不变。)
谢谢!
发布于 2010-05-20 12:31:45
他们俩是一样的。您在BackgroundWorker
中看到的电话使用SynchronizationContext
。实际上,Post()
方法的默认实现使用线程池,但是在启动Windows应用程序时,默认的同步上下文被WindowsFormsSynchronizationContext
所取代,后者实际上调用了Control.BeginInvoke()
。
发布于 2010-05-19 13:46:01
一个很大的区别是Control.Invoke
会阻塞直到UpdateGUI调用被执行和完成,而BackgroundWorker.ReportProgress
不会阻塞(在BackgroundWorker引发事件之前,它会立即返回)。
如果希望它们的行为相同,则调用Control.BeginInvoke
(而不是阻塞)。
发布于 2010-07-04 10:03:04
我发现了一个很大的区别。在BGW运行时关闭表单将导致this.Invoke()和this.BeginInvoke()抛出一个ObjectDisposedException。BGW的ReportProgress机制绕过了这一点。为了享受这两个世界的最佳状态,下面的模式工作得很好
public partial class MyForm : Form
{
private void InvokeViaBgw(Action action)
{
Packing_Worker.ReportProgress(0, action);
}
private void BGW_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (this.IsDisposed) return; //You are on the UI thread now, so no race condition
var action = (Action)e.UserState;
action();
}
private private void BGW_DoWork(object sender, DoWorkEventArgs e)
{
//Sample usage:
this.InvokeViaBgw(() => MyTextBox.Text = "Foo");
}
}
https://stackoverflow.com/questions/2865971
复制相似问题