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

У меня есть основная форма, которая запускает поток BackgroundWorker. Пока рабочий работает, я «замораживаю» основную форму и жду ее завершения, показывая ее прогресс.

В одном из сценариев рабочий может отображать диалоговое окно OpenFileDialog, чтобы пользователь мог выбрать файл. Я использую третий поток для запуска OpenFileDialog и устанавливаю для него ApartmentState значение STA, поскольку этого требует OpenFileDialog (выдает исключение, если я этого не делаю), а рабочий объект ApartmentState — это MTA.

Проблема в том, что я хочу передать потоку OpenFileDialog основную форму в качестве параметра, чтобы ее можно было использовать при вызове OpenFileDialog.ShowDialog. Что-то вроде этого:

public void ThreadProcShowDialog(object param)
{
    Form parent = (Form)param;
    dialog.ShowDialog(parent);
}

Конечно, ShowDialog выдает:

Недопустимая межпоточная операция: доступ к элементу управления «Форма» осуществляется из потока, отличного от потока, в котором он был создан.

Как я могу сделать это потокобезопасным способом?

Целью этого является то, что OpenFileDialog будет работать в потоке STA, блокируя отображение основной формы поверх него (запретить пользователю щелкать форму ниже, тем самым скрывая OpenFileDialog).

Спасибо


person Yoram    schedule 10.01.2012    source источник


Ответы (1)


Нашел!

Со мной работал коллега-программист, который предложил простое решение, которое действительно сработало. Вместо того, чтобы запускать OpenFileDialog в третьем потоке, просто запустите его в основной форме (той, которая запустила рабочий поток.

Это выглядит так:

//Code inside worker method
OpenFileDialog dialog= new OpenFileDialog();
DialogResult result = DialogResult.None;

Invoke(new MethodInvoker(delegate() { result = dialog.ShowDialog(this); }));
if (result == DialogResult.OK)
{
    ...
}

Таким образом, я блокирую основную форму от щелчка, и OpenFileDialog запускается в потоке STA.

И если подумать, тот, кто решил это, — программист на C++. ;-)

Я надеюсь, что это будет полезно для кого-то...

person Yoram    schedule 11.01.2012