使用C#2.0和MethodInvoker委托,我有一个GUI应用程序从GUI线程或工作线程接收一些事件。
我使用以下模式处理表单中的事件:
private void SomeEventHandler(object sender, EventArgs e)
{
MethodInvoker method = delegate
{
uiSomeTextBox.Text = "some text";
};
if (InvokeRequired)
BeginInvoke(method);
else
method.Invoke();
}
通过使用这种模式,我不会复制实际的UI代码,但我不确定的是这种方法是否合适。
特别是行
method.Invoke()
它是否使用另一个线程进行调用,或者它是否稍微转换为直接调用GUI线程上的方法?
答案 0 :(得分:21)
method.Invoke()
调用在当前正在执行的线程上执行委托。使用BeginInvoke(method)
可确保在GUI线程上调用委托。
当从GUI线程和其他线程调用相同的方法时,这是避免代码重复的正确方法。
答案 1 :(得分:15)
我个人喜欢这种方法:
private void ExecuteSecure(Action a)
{
if (InvokeRequired)
BeginInvoke(a);
else
a();
}
然后你可以这样编写单行:
ExecuteSecure(() => this.Enabled = true);
答案 2 :(得分:5)
请记住,如果您在后台线程并且Control.IsHandleCreated为false,则Control.InvokeRequired返回false。我会使用Debug.Assert来保护代码,以检查是否存在非托管句柄。
答案 3 :(得分:2)
对于WinForms,调用Control.Invoke(Delegate)
会向UI的thead的消息泵发送消息。然后,线程处理消息并调用委托。处理完毕后,Invoke
将停止阻塞,并且调用线程将继续运行您的代码。
答案 4 :(得分:0)
它在同一个线程上进行调用。您可以通过单步执行代码来检查。这种方法没有错。