Чтобы использовать диалоговые окна в приложениях с окнами, либо основной поток должен быть установлен как [STAThread]
, либо для запуска диалогового окна необходимо создать отдельный поток STA.STA поток для диалоговых окон
Вот и проблема, которую я не мог понять. Начальный поток STA не заканчивается «иногда», поэтому основной поток продолжает зависать на Join().
Теперь я преодолел с помощью Application.DoEvents()
вместо t.Join()
, и теперь кажется, что он работает нормально, но меня все равно интересует, что «иногда» в зависимости от. В примере я использую следующий статический метод, чтобы открыть в openfile-/SAVEFILE диалог:
using System.Windows.Forms;
namespace Dialog
{
public class clsDialogState
{
public DialogResult result;
public FileDialog dialog;
public void ThreadProcShowDialog()
{
result = DialogResult.None;
result = dialog.ShowDialog();
}
}
public static class clsShowDialog
{
public static DialogResult STAShowDialog(FileDialog dialog)
{
clsDialogState state = new clsDialogState();
state.dialog = dialog;
System.Threading.Thread t = new System.Threading.Thread(state.ThreadProcShowDialog);
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
//t.Join(); //Main thread might hang up here
while (state.result == DialogResult.None) Application.DoEvents(); //Everything is refreshed/repainted fine
return state.result;
}
}
}
Так использование просто просто:
Dialog.clsShowDialog.STAShowDialog(new SaveFileDialog());
В основном компоненты пользовательского интерфейса (COM) вообще не являются ThreaSafe и не будут работать должным образом в средах MTA. – codeteq
Когда вы объявляете поток STA, вы обещаете, что вы не будете блокировать поток, и у вас будет насос сообщений. Если вы блокируете поток STA или у вас нет сообщения, то на него могут случиться случайные плохие вещи. См. [Этот ответ] (http://stackoverflow.com/a/4530773/80274) для получения более подробной информации. –
@ScottChamberlain Правда, но 'Thread.Join' * - это перекачивание. Я подозреваю, что это будет нормально работать, если вызывающий абонент не был потоком пользовательского интерфейса. – Luaan