none
OpenFileDialog ShowDialog()에 대한 Hang이 일어나는 원인을 이해하기 위한 힌트좀 부탁드립니다. RRS feed

  • 질문

  • using System;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;
    
    class test : Form
    {
        //1.
        //[STAThreadAttribute]
        public static void Main()
        {
            Application.Run(new test());
        }
    
        public test()
        {
            Menu = new MainMenu();
            Menu.MenuItems.Add("&File");
            Menu.MenuItems[0].MenuItems.Add("&Open...", new EventHandler(MenuFileOpenOnClick));
        }
    
        private void MenuFileOpenOnClick(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            
            //2.
            //openFileDialog1.AutoUpgradeEnabled = false;
    
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
            //처리되지 않은 'System.Threading.ThreadStateException' 
            //형식의 예외가 System.Windows.Forms.dll에서 발생했습
            //니다.
    
            //추가 정보: OLE 호출을 수행하려면 현재 스레드를 
            //STA(단일 스레드 아파트) 모드로 설정해야 합니다. 
            //표시된 STAThreadAttribute가 Main 함수에 있는지 
            //확인하십시오. 이 예외는 디버거가 프로세스에 연결된 
            //경우에만 발생합니다.
                
            }
        }
    }
    
    
    설명:
      오류로 인해 이 프로그램이 Windows와 상호 작용하지 않습니다.
    
    문제 서명:
      문제 이벤트 이름: AppHangB1
      응용 프로그램 이름: Chapter16.exe
      응용 프로그램 버전: 0.0.0.0
      응용 프로그램 타임스탬프: 55549c0c
      중단 서명: 6fdf
      중단 유형: 524
    
    

    OLE 정보

    https://msdn.microsoft.com/ko-kr/library/cc485693(v=vs.71).aspx

    STAThreadAttribute

    https://msdn.microsoft.com/ko-kr/library/vstudio/system.stathreadattribute(v=vs.100).aspx

    포인트:

    .NET Framework 버전 2.0에서는 새 스레드가 시작되기 전에 해당 스레드의 아파트

    상태가 설정되지 않았으면 이 스레드는 ApartmentState.MTA로 초기화됩니다.  기

    본 응용 프로그램 스레드는 기본적으로 ApartmentState.MTA로 초기화됩니다.  더

    이상 코드의 첫째 줄에서 Thread.ApartmentState 속성을 설정하여 기본 응용 프로

    그램 스레드를 ApartmentState.STA로 설정할 수 없습니다.  대신

    STAThreadAttribute를 사용합니다.

    사용 IDE : Vs2013 community

    .net Framework 4

    명쾌하게 제가 설명을 못하겠습니다.

    디자인으로 하다가 코드로 하니깐 뭔가 색다릅니다.

    단순하게 보면 저 샘플에서 OpenFileDialog를 사용하기 위해서는 STA설정이 필요하다는건데..

    원인을 정확히 이해하기에는 제가 많이 부족한거 같습니다.

    그리고,

    1번 방법을 사용하면 win7 OpenFileDialog 모양을 그대로 가져오고

    2번 방법을 사용하면 모양이 좀 틀린 OpenFileDialog를 가져옵니다.

    원인을 이해하기 위한 힌트를 주시면 감사하겠습니다.




    • 편집됨 바보푸우 2015년 5월 14일 목요일 오후 3:44
    2015년 5월 14일 목요일 오후 1:52

답변

  • 전체를 완벽하게 이해하고 싶다면 COM 기술을 알아야 합니다.

    .NET Framework도 결국 운영체제의 기능을 사용하고 있고, OpenFileDialog의 경우 내부적으로 COM 기술을 사용하기 때문에 이런 제약이 발생하는 것입니다. OpenFileDialog 내부적으로 사용하고 있는 COM 객체가 STA 유형이기 때문에, 그것을 생성하는 스레드의 Apartment 유형이 STA임을 요구합니다.

    따라서, 1번 주석을 제거하면 안됩니다.

    2번의 경우 모양이 틀린 것은 옵션에 따라 바뀌도록 내부적으로 프로그램이 되어 있었을 테니, 그다지 이상한 동작은 아닐 듯 싶습니다.

    • 답변으로 표시됨 바보푸우 2015년 5월 15일 금요일 오전 1:59
    2015년 5월 15일 금요일 오전 1:25

모든 응답

  • 전체를 완벽하게 이해하고 싶다면 COM 기술을 알아야 합니다.

    .NET Framework도 결국 운영체제의 기능을 사용하고 있고, OpenFileDialog의 경우 내부적으로 COM 기술을 사용하기 때문에 이런 제약이 발생하는 것입니다. OpenFileDialog 내부적으로 사용하고 있는 COM 객체가 STA 유형이기 때문에, 그것을 생성하는 스레드의 Apartment 유형이 STA임을 요구합니다.

    따라서, 1번 주석을 제거하면 안됩니다.

    2번의 경우 모양이 틀린 것은 옵션에 따라 바뀌도록 내부적으로 프로그램이 되어 있었을 테니, 그다지 이상한 동작은 아닐 듯 싶습니다.

    • 답변으로 표시됨 바보푸우 2015년 5월 15일 금요일 오전 1:59
    2015년 5월 15일 금요일 오전 1:25
  • 덕분에 어떠한걸 찾아봐야 하는지 알겠습니다.

    좋은 가르침 감사합니다.

    2015년 5월 15일 금요일 오전 1:58