Использование C # MethodInvoker.Invoke () для приложения с графическим интерфейсом ... это хорошо? - PullRequest
26 голосов
/ 23 апреля 2009

Используя C # 2.0 и делегат MethodInvoker, у меня есть приложение с графическим интерфейсом, получающее событие из потока графического интерфейса или из рабочего потока.

Я использую следующий шаблон для обработки события в форме:

private void SomeEventHandler(object sender, EventArgs e)
{
    MethodInvoker method = delegate
        {
            uiSomeTextBox.Text = "some text";
        };

    if (InvokeRequired)
        BeginInvoke(method);
    else
        method.Invoke();
}

Используя этот шаблон, я не дублирую реальный код пользовательского интерфейса, но я не уверен, хорош ли этот метод.

В частности, линия

method.Invoke()

использует ли он другой поток для вызова или это несколько переводит в прямой вызов метода в потоке GUI?

Ответы [ 5 ]

21 голосов
/ 23 апреля 2009

Вызов method.Invoke() выполняет делегат в текущем исполняющем потоке. Использование BeginInvoke(method) гарантирует, что делегат вызывается в потоке GUI.

Это правильный способ избежать дублирования кода, когда один и тот же метод может быть вызван как из потока GUI, так и из других потоков.

15 голосов
/ 05 ноября 2011

Лично мне нравится этот метод:

private void ExecuteSecure(Action a)
{
    if (InvokeRequired)
        BeginInvoke(a);
    else
        a();
}

И тогда вы можете написать однострочники так:

ExecuteSecure(() => this.Enabled = true);
5 голосов
/ 28 апреля 2009

Имейте в виду, что Control.InvokeRequired возвращает false, если вы находитесь в фоновом потоке, а Control.IsHandleCreated имеет значение false. Я бы защищал код с помощью Debug.Assert, который проверяет создание неуправляемого дескриптора.

2 голосов
/ 23 апреля 2009

Для WinForms, вызов Control.Invoke(Delegate) отправляет сообщение в рассылку сообщений thead пользовательского интерфейса. Затем поток обрабатывает сообщение и вызывает делегата. После обработки Invoke прекращает блокировку, и вызывающий поток возобновляет выполнение вашего кода.

0 голосов
/ 23 апреля 2009

Это делает вызов в той же теме. Вы можете проверить, пройдя по коду. В этом подходе нет ничего плохого.

...