Установка Form.Owner для формы из другого потока - PullRequest
0 голосов
/ 02 ноября 2009

Мое приложение (C #, VS2008) загружает информацию из базы данных (SQL Server 2008 Express) по сети. Во время (возможно) долгого ожидания я хочу, чтобы диалоговое окно «Загрузка ...» отображалось в другом потоке, но только если операция занимает больше определенного периода времени (скажем, 500 мс).

Итак, моя форма загрузки отображается после 500 мс (если операция длится так долго) без установки владельца формы диалога загрузки (т. Е. Вызова LoadingDialog.ShowDialog ()), но при попытке вызвать LoadingDialog. ShowDialog (владелец IWin32Window) с владельцем, установленным в основную форму (передается через параметр потока). Я получаю исключение InvalidOperationException о доступе к элементам управления между потоками.

Мой основной вопрос: могу ли я создать и ShowDialog форму с параметром владельца, установленным для формы в другом потоке? Я хочу сделать это так, чтобы диалог загрузки был модальным для остальной части приложения, то есть, как и любой другой диалог, фокусировался и запрещал ввод в другом месте.

Может кто-нибудь предложить предложение? Я прочитал кучу об заставках без удачи, а также об Invoke и BeginInvoke без удачи. Есть ли другой способ, которым я должен идти об этом?

Пожалуйста, не стесняйтесь просить разъяснений, если вы не понимаете.

Merci (как говорят по-французски),

Jacob.

Ответы [ 3 ]

1 голос
/ 05 ноября 2010

Вы МОЖЕТЕ создать столько потоков пользовательского интерфейса, сколько захотите. Следующий код должен сделать трюк:

    Thread thread = new Thread(new ThreadStart(() => Application.Run(new MyForm())));
    thread.SetApartmentState(ApartmentState.STA);
    thread.IsBackground = true;
    thread.Start();
1 голос
/ 26 апреля 2011

Вы должны запустить свой длинный процесс в фоновом потоке, а затем показать форму Загрузка ... в виде немодального диалога. Таким образом, пользователь может видеть индикацию загрузки, но все же взаимодействовать с другими частями системы во время ее работы.

Другим вариантом будет показ прогресса загрузки в строке состояния или аналогичной. Главное - убедиться, что длинная операция выполняется в фоновом потоке, а вся логика графического интерфейса - в потоке графического интерфейса.

Хороший формат потоков может выглядеть следующим образом (это просто псевдокод для демонстрационных целей - вам нужно использовать Invoke, чтобы получить соответствующие потоки):

RunInBackground(DoLongOperation);
ShowLoadingDialog();
...

DoLongOperation()
{
    LongOperation();
    RunOnGUI(FinishLongOperation);
}

FinishLongOperation()
{
   CloseLoadingDialog();
}
1 голос
/ 02 ноября 2009

Все компоненты пользовательского интерфейса работают в одном единственном потоке, который проходит через цикл сообщений win32. Вы не можете запустить любой компонент пользовательского интерфейса в другом потоке. Эта архитектура сохраняется начиная с Windows 3.1.

...