Использование C# MethodInvoker.Invoke () для приложения GUI... это хорошо?

используя 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();
}

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

в частности, строку

method.Invoke()

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

5 ответов


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

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


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

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

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

ExecuteSecure(() => this.Enabled = true);

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


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


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