MessageBox.Show () автоматически маршаллирует в поток пользовательского интерфейса? - PullRequest
11 голосов
/ 18 февраля 2009

Я запускаю поток через ThreadPool.QueueUserWorkItem, в котором есть диалоговое окно сообщения:

System.Windows.Forms.DialogResult dr = System.Windows.Forms.MessageBox.Show («Вы хотите загрузить обновление в фоновом режиме? ..», «Обновление доступно», MessageBoxButtons.YesNo);

Кажется, это работает нормально, однако я немного подозрительно после того, как некоторые клиенты предположили, что они не получают сообщение. У меня было ощущение, что в .NET Framework 2.0+ вам не нужно маршалировать этот конкретный вызов, он делает это для вас. Правильно?

Это полуоткрытая тема для интереса: Зачем использовать окно владельца в MessageBox.Show?

Ответы [ 4 ]

17 голосов
/ 18 февраля 2009

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

Возможно иметь более одного потока пользовательского интерфейса в приложении. Некоторые программы, такие как Internet Explorer, имеют множество потоков пользовательского интерфейса. Какой поток пользовательского интерфейса выберет .Show call?

Также возможно использовать MessageBox.Show в приложении, в котором нет потоков пользовательского интерфейса. Вы можете очень хорошо назвать это в консольном приложении, и оно будет работать.

MessageBox.Show покажет пользовательский интерфейс в потоке, из которого он вызывается. Если в потоке еще не работает насос сообщений, он настроит временный насос для работы. После завершения вызова Show он будет разорван.

7 голосов
/ 18 февраля 2009

Как правило, вы не должны выполнять работу с графическим интерфейсом вне основного потока / потока приложения. Я бы сделал метод ShowMessageBox в родительской форме, который может сделать Invoke:

public DialogResult ShowMessageBox (String message, String caption)
{
    if (this.InvokeRequired) {
        return (DialogResult) this.Invoke (new PassStringStringReturnDialogResultDelegate (ShowMessageBox), message, caption);
    }
    return MessageBox.Show (this, message, caption);
}

public delegate DialogResult PassStringStringReturnDialogResultDelegate (String s1, String s2);

НО ТАКЖЕ ПРОДОЛЖАЙТЕ: при отладке многопоточного приложения с графическим интерфейсом и при отладке в потоке, отличном от основного потока / потока приложения, ВЫ ДОЛЖНЫ ВЫКЛЮЧИТЬ «Включить оценку свойства и другие неявные вызовы функций» option, иначе VS будет автоматически извлекать значения локальных / глобальных объектов GUI ИЗ ТЕКУЩЕЙ РЕЗЬБЫ, что приведет к аварийному завершению / сбою приложения. Перейдите в Инструменты-> Параметры-> Отладка, чтобы отключить этот параметр.

Извините за заглавные буквы, но мне потребовались ДНИ, чтобы понять, почему я каждый раз, когда я пытался отладить свое приложение, зависало, а затем вылетало.

5 голосов
/ 18 февраля 2009

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

0 голосов
/ 18 февраля 2009

Это приложение или услуга. Если это служба, возможно, она не настроена с разрешением «Разрешить взаимодействие с рабочим столом».

См. Свойства службы в апплете панели управления службами.

...