Windows 응용 프로그램에서 대화 상자를 사용하려면 주 스레드를 [STAThread]
으로 설정하거나 대화 상자를 실행하기 위해 별도의 STA 스레드를 만들어야합니다.대화 상자에 대한 STA 스레드
내가 실제로 이해할 수없는 문제가 여기에 있습니다. 시작된 STA 스레드가 "가끔"완료되지 않으므로 주 스레드가 Join()에서 끊어지지 않습니다.
이제는 t.Join()
대신 Application.DoEvents()
을 사용하여 극복하고 이제는 정상적으로 작동하는 것처럼 보이지만 여전히 "때때로"에 의존하고 있습니다.
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());
대부분 UI 구성 요소 (COM)는 ThreaSafe가 아니며 MTA 환경에서 제대로 실행되지 않습니다. – codeteq
스레드 STA를 선언 할 때 스레드를 차단하지 않고 메시지 펌프를 실행하겠다는 약속을합니다. STA 스레드를 차단하거나 메시지 펌프가 없으면 임의적으로 나쁜 일이 발생할 수 있습니다. 자세한 내용은 [이 답변] (http://stackoverflow.com/a/4530773/80274)을 참조하십시오. –
@ScottChamberlain 참,하지만'Thread.Join' *은 펌핑 대기 중입니다. 호출자가 UI 스레드가 아닌 경우이 작동합니다 의심. – Luaan