使用C#MethodInvoker.Invoke()获取GUI应用程序......这样好吗?

时间:2009-04-23 15:29:51

标签: c# multithreading c#-2.0 invoke

使用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线程上的方法?

5 个答案:

答案 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)

它在同一个线程上进行调用。您可以通过单步执行代码来检查。这种方法没有错。