NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    Error 관리 디버깅 도우미 'ContextSwitchDeadlock' : 'CLR에서 60초 동안 COM 컨텍스트 <0x0000…

    페이지 정보

    본문

    비주얼 스튜디오에서 장시간 스레드로 작업할 때 아래와 같은 경고 메세지가 표시될 수 있습니다.

    I7LFsQI.png

    관리 디버깅 도우미 'ContextSwitchDeadlock' : 'CLR에서 60초 동안 COM 컨텍스트 0x9f7e6400에서 COM 컨텍스트 0x9f7e69c8(으)로 전환하지 못했습니다. 
    대상 컨텍스트/아파트를 소유하는 스레드가 펌프 대기를 수행하지 않거나, Windows 메시지를 펌프하지 않고 매우 긴 실행 작업을 처리하고 있는 것 같습니다. 
    이러한 상황은 대개 성능에 부정적인 영향을 주며 응용 프로그램이 응답하지 않거나 시간이 흐름에 따라 메모리 사용이 증가하는 문제로 이어질 수도 있습니다. 
    이 문제를 방지하려면 모든 STA(Single Threaded Apartment) 스레드가 펌프 대기 기본 형식(
        예: CoWaitForMultipleHandles
    )을 사용하고 긴 실행 작업 동안 지속적으로 메시지를 펌프해야 합니다.'

     

    비주얼 스튜디오가 코드에 문제가 발생할 수 있다고 경고해주는 내용을 잘 보면 해답을 얻을 수 있습니다. 제 경우에는 Windows File System(IO)에 계속해서 메세지를 기록하고 있습니다. 이 때 스트림(Stream)을 사용하고, UI 작업자 스레드가 아닌 별도의 스레드가 이 내용을 처리합니다. 보통 스트림에 텍스트를 기록할 때 아래와 같은 코드를 사용합니다.

                FileStream stream = new FileStream(_logFile.FullName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                StreamWriter sw = new StreamWriter(stream);
    
                try
                {
                    sw.Write($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}] {text}");
                    _logFile.Refresh();
                }
                catch (Exception ex)
                {
                    Console.Write($"{ex.Message}{Environment.NewLine}{ex.StackTrace}");
                }
                finally
                {
                    sw.Flush();
                    sw.Close();
                    sw = null;
                    stream.Close();
                    stream = null;
                }

     

    Stream 객체의 Flush()를 호출해서 버퍼를 지워주면 문제가 없을거 같지만, 실상은 그렇지 않습니다. 여전히 ContextSwitchDeadlock 경고를 발생시킵니다. 에러는 아니지만, 디버깅 타임에 발생되는 경고라서 무시해도 됩니다. 하지만, 이 문제를 근본적으로 해결하려면 try ~ catch ~ finally에서 finally쪽 마지막에 아래 코드를 추가해야 합니다.

    System.Threading.Thread.Sleep(10);

     

    이렇게하면 문제가 해결되지만... 음~ 원하는건 아닙니다. 계속해서 로그를 기록해야 하는데... 로그 한줄 작성할 때마다 0.01초를 쉬어야 한다면 퍼포먼스를 해치게 됩니다. 그래서, 실제 코드에서 문제가 되지는 않지만 하나의 스레드를 너무 오랜시간 점유해서 문제가 될거 같다고 알려주는 경고를 디버깅 타임에 해제하는게 좋습니다. 아래 그림과 같이 디버그 메뉴에서 창 > 예외 설정으로 이동하세요.

    9I1Z0lQ.png

     

     

    예외 설정에서 ①context 를 검색한 후 ②ContextSwitchDeadlock 체크를 해제하세요. 더이상 경고가 발생하지 않을겁니다~

    izdecmu.png

     

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

     

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.