问候,我正在用C#开发一些应用程序 . 目前我正在处理线程,我有一个问题,我在脑海里 . Invoke和BeginInvoke有什么区别?我读了一些帖子,我在这里找到了一些有用的信息:here
但是,以下代码中的Invoke和BeginInvoke之间有什么区别:
private void ProcessRoutine()
{
for (int nValue = StartFrom; nValue <= EndTo; nValue++)
{
this.Invoke(this.MyDelegate, nValue);
//this.BeginInvoke(this.MyDelegate, nValue);
}
MessageBox.Show("Counting complete!");
}
private void MessageHandler(int progress)
{
lblStatus.Text = lblStatus.Text = "Processing item: " + progress.ToString();
progressBar1.Value = progress;
}
其中MyDelegate是对MessageHandler函数的引用 .
我注意到使用BeginInvoke lblStatus.Text没有刷新,使用Invoke刷新标签 . 另外我知道Invoke等待它的执行完成 . 我感兴趣的最重要的案例是为什么在这种情况下刷新标签文本会有所不同 .
5 回答
使用Invoke,方法将被执行,应用程序将等待它完成 .
使用BeginInvoke,方法被Asychnronously调用,应用程序继续执行,同时执行BeginInvoke中引用的方法 .
使用BeginInvoke,您需要调用EndInvoke来获取使用BeginIvnoke执行的方法的结果 .
您不应该更新BeginXXX方法中的GUI组件,因为它们在另一个线程中运行到GUI线程,这与您的Invoke方法相反 . 您无法在与GUI线程不同的线程中访问GUI组件 .
希望这可以帮助!
首先,从您的链接:
Control.Invoke
:在UI线程上执行,但调用线程在继续之前等待完成 .Control.BeginInvoke
:在异步UI线程上执行,调用线程不等待完成 .从MSDN:
总结一下,
BeginInvoke
是异步的 . 当从UI线程调用BeginInvoke
时,请求将与UI线程并行执行 . 这意味着它可能直到当前正在执行的方法返回后才执行 . 因此,在这种情况下,文本框将永远不会更新,因为for循环不会被中断,因为调用线程不会等待此事件在继续之前完成 .或者,
Invoke
是同步的 . 文本框将被更新,因为调用线程将在继续执行之前等待调用完成 .Control.BeginInvoke
不是't work on a different thread (or threadpool), a delegate.BeginInvoke does. MSDN'的一个班轮说:但是
Control.BeginInvoke
只是使用PostMessage并返回 - 没有创建CLRThread
.This article总结了是否使用
Invoke
或BeginInvoke
:BeginInvoke在另一个线程上执行方法体,并允许当前线程继续 . 如果您尝试直接从另一个线程更新控件属性,它将引发异常 .
这基本上归结为您是否希望同步或异步更新控件 . 这一切都取决于您的具体情况 .