2017-02-03 18 views
0

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()); 
+0

대부분 UI 구성 요소 (COM)는 ThreaSafe가 아니며 MTA 환경에서 제대로 실행되지 않습니다. – codeteq

+0

스레드 STA를 선언 할 때 스레드를 차단하지 않고 메시지 펌프를 실행하겠다는 약속을합니다. STA 스레드를 차단하거나 메시지 펌프가 없으면 임의적으로 나쁜 일이 발생할 수 있습니다. 자세한 내용은 [이 답변] (http://stackoverflow.com/a/4530773/80274)을 참조하십시오. –

+1

@ScottChamberlain 참,하지만'Thread.Join' *은 펌핑 대기 중입니다. 호출자가 UI 스레드가 아닌 경우이 작동합니다 의심. – Luaan

답변

1

내가 호출 스레드 매달려하게 정확하게 알아낼 수있는 예에서 나는 openfile-/savefile을 대화 상자를 열려면 다음과 같은 정적 인 방법을 사용 STA 스레드가 끝나기를 기다리고있을 때 join()을 수행하지만 가끔씩 작동하는 것처럼 보일 때가 있습니다. 마지막으로 Join() 대신에

while (InvokeResult == DialogResult.None) Application.DoEvents(); 

을 사용하여 극복하기로 결정했습니다.