为什么在这里使用BeginInvoke?

时间:2010-02-18 07:07:32

标签: c# .net delegates begininvoke

我正在研究其他人的代码,并且没有太多与多线程有关的经验。我遇到了这行代码:

BeginInvoke((MethodInvoker)delegate() { btnCalibrate.PerformClick(); });

我想知道为什么这样做会有效:btnCalibrate.PerformClick();

感谢您的回答。

2 个答案:

答案 0 :(得分:6)

因为如果此代码在与GUI中创建按钮的线程不同的线程中运行,则会抛出异常。后台线程无法直接调用GUI上的方法,因为GUI不是线程安全的。

当然,这只是使用BeginInvoke的合理原因!但是,找到包含刚刚放入的咒语或魔法咒语的代码并不是很常见,因为作者已经看到了另一个以这种方式做到这一点的例子,所以假设它必须在所有情况下都是必要的。如果你正在使用的代码是单线程的,那么就没有必要了。

特别是,Windows Forms本身是坚定的单线程。所有窗口和控件上的所有操作都发生在同一个线程上,并且所有事件都在同一个线程上触发。一个GUI线程的使用通过在线程上连续运行并从队列中读取消息的消息循环进行分区。 BeginInvoke的目的是最终将消息发布到该队列,有效地说“当你有片刻时,请运行这段代码。”

答案 1 :(得分:1)

要扩展@Earwicker - Control.BeginInvoke是一种将调用从一个线程传输到拥有Control实例的线程的方法。在后台,它通过名为PostMessage的Win32函数使用Win32消息来编组对拥有线程上的方法PerformClick的调用。这是需要的,因为Win32 Windows和扩展WinForms控件只能从创建它的线程安全访问,这通常是运行GUI的单个线程。

使用BeginInvokeInvoke的原因是因为前者使用PostMessage并立即返回,而后者使用 SendMessage,并需要等待 PostMessage并等待GUI线程的回复。这可以延迟线程进行调用甚至锁定应用程序,因此BeginInvoke是更好的选择。