Console Application 에서 Console.WriteLine 이 업데이트 되지 않는 현상을 겪으신분 있으실까요?

안녕하세요.
도저히 원인을 찾을 수 없어 혹시 유사한 경험을 하신분의 고견을 듣고자 합니다.

오랜만에 콘솔 환경에서 동작하는 어플레케이션을 작성 하였습니다.
잘 작동 하다가 어느순간, Exception 도 발생 하지 않았지만 특별한 이유 없이 앱의 Console 화면이 업데이트 되지 않는 현상이 간헐적으로 발생 하고 있습니다. 물론 커서는 계속 깜박입니다.

이 문제를 정확히 추적하기 위하여, 주기적으로 반복 처리 되는 Thread에 1분마다 (아래화살표) 와 같은 문자열을 출력 하도록 해놨습니다.


위의 화면은 문제가 발생한 상황으로서 우측하단 시계를 기준으로 생각해보면 충분히 1분을 초과 하였으니, 작성된 한줄이 나와야 함에도 불구 하고 묵묵무답입니다.

그리고,


위의 화면은 앱이 반응 하지 않을때 해당 Cmd 창을 살짝 움직여 본 것일뿐 입니다. 그제서야 해당 시간과 타이밍에 표시되야 할 내용(a)이 한번에 업데이트가 됩니다.

사실 화면만 업데이트가 안된다면 정말 다행이겠으나, 해당 현상이 나올때는 통신 Thread 와 타이밍을 체크 하는 각종 스레드 역시 모두 작동 하지 않는 상황입니다.

이 현상이 무언가 잘못 작성된 코드가 원일 일까요?
혹시 유사한 현상을 겪으셨거나 나름의 방법이 있으신분들의 응답을 기다립니다.

답답한마음에, 화면을 녹화 하여 링크를 첨부 합니다.
문제발생당시영상

감사합니다.

  • [개발 환경]
    OS : 윈도우즈 11
    프레임워크 : .NET8
1 Like

현상만 보고 말할 수 있는 내용이 많지 않습니다. 다만 코드 없이 경험에만 의존하여 답을 하나 드려보면, 콘솔도 버퍼가 있고, 이 버퍼에 쌓아두기만 할 여지가 있습니다. (일반적인 스트림이 그러하듯이)

어떻게 입출력이 진행되는지 알수는 없으나 콘솔에 플러시 처리를 별도로 해주어야 하는 상황은 아닌지 의견을 드려봅니다.

1 Like

스레드 락이 의심이 됩니다

1 Like

당연히 이 문제는 아닐 것 같은데 혹시나 해서 댓글을 남겨봅니다.

위 그림에서 저렇게 흰색으로 보이는 부분이 있는 걸 보니 콘솔이 마우스 드래그로 인한 “선택 모드” 상태 인 것 같은데요, "선택 모드"에서는 원래 업데이트가 안되는데 혹시 그 이유 때문이 아닐까요? :sweat_smile:

4 Likes

감사합니다. 눈썰미가 좋으시네요.

업데이트 드립니다.

image

@al6uiz 님께서 조언 주신대로 사고 실험을 해보니 (좌측) 콘솔 어플리케이션의 문자열들을 드래그 한 채 방치 하면 업데이트가 되지 않는 현상을 발견하였고 앞서 기술한대로 해당 앱에서 돌고 있는 통신Thread 조차 응답 하지 않는것으로 확인하였습니다.

사실 이와 동일 한구성으로 각기 다른 8개의 시스템을 구성 하였는데 모든 어플리케이션이 위의 사고 실험결과를 보이진 않아 차이점을 분석 하였습니다.

  1. 상단 이미지 (a)의 앱 아이콘으로 유추 하여 보듯 exe 더블클릭하여 실행하면 어떤 것들은 좌측 처럼 어플리케이션이 따로 띄어 지고, 다른 것들은 윈도우의 cmd 위에서 띄어짐을 발견 하였습니다.

  2. 그리고 동일하게 화면을 드래그 하여 사고 실험을 진행 했고~

  3. 결과로 (b) 영역을 보시면 우측 이미지 처럼 콘솔로 띄어진 부분은 업데이트가 정상적으로 되고, 역시 다른 Thread들도 모두 동작 하였습니다.

  4. 그리고 큰 차이점중 하나가 윈도우 버전인데 (c) 좌측 문제가 있는 PC의 버전은 21H2 입니다.

  5. 아래 인디케이터에서 볼 수 있듯 이 관찰 및 실험 결과는 다른 여러 PC에서도 일관된 결과를 보였습니다. 정상 동작 하는 2,3,9 번 PC는 이미지의 우측과 같은 환경 입니다.

가장 활실한 해결책을 생각한다면 윈도우를 22H2 까지 업데이트를 하거나 , 우측 처럼 실행 될 수 있게 콘솔창 옵션을 수정 해야 할 것으로 보입니다.

콘솔창 옵션은 해당 옵션을 해제 하면 더이상 드래깅이 되지 않는것으로 확인 하였습니다.

연휴인데도 불구 하고 답을 주셔서 정말 감사드립니다.

4 Likes

조언 감사합니다.
안그래도 적절히 Console.Clear() 로 대신 할 수 있을까 하여 활용 하였는데, Flush 라는 확실한 방법이 있었네요.

3 Likes

감사합니다. 다시한번 코드를 분석 해 보겠습니다.

2 Likes

당연히 이 문제 였습니다…
선택 상태를 해제 하려면 마우스 우클릭 이면 되는군요. 이렇게 하나더 배워 갑니다.

드래그 한뒤에 몇번 인위적으로 로그를 미뤄둔 이후 마우스 우클릭으로 선택상태를 해제 하니 한번에 쫙 업데이트 되며 일시정지 상태가 해제 되었습니다.
(콘솔창에 밝은 드래깅 라인을 조심해야 겠습니다)
감사합니다

4 Likes

덧붙입니다. 이 EditMode를 코드로 비활성화 할 수 있는 방법을 찾았습니다.
출처

using System;
using System.Runtime.InteropServices;

static class DisableConsoleQuickEdit {

   const uint ENABLE_QUICK_EDIT = 0x0040;

   // STD_INPUT_HANDLE (DWORD): -10 is the standard input device.
   const int STD_INPUT_HANDLE = -10;

   [DllImport("kernel32.dll", SetLastError = true)]
   static extern IntPtr GetStdHandle(int nStdHandle);

   [DllImport("kernel32.dll")]
   static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);

   [DllImport("kernel32.dll")]
   static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

   internal static bool Go() {

      IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);

      // get current console mode
      uint consoleMode;
      if (!GetConsoleMode(consoleHandle, out consoleMode)) {
         // ERROR: Unable to get console mode.
         return false;
      }

      // Clear the quick edit bit in the mode flags
      consoleMode &= ~ENABLE_QUICK_EDIT;

      // set the new mode
      if (!SetConsoleMode(consoleHandle, consoleMode)) {
         // ERROR: Unable to set console mode
         return false;
      }

      return true;
   }
}
5 Likes