'InvalidOperationException'에 해당되는 글 1건

  1. 2010.04.23 크로스 스레드 작업. 1
C#2010. 4. 23. 19:55

#. 내용.
  닷넷 UI를 사용하는 프로그램을 제작하다가 이런 메시지를 보았습니다.
 - "크로스 스레드 작업이 잘못되었습니다. 'm_listBoxMessages' 컨트롤이 자신이 만들어진 스레드가 아닌 스레드에서 액세스되었습니다."

  FTP Server를 제작하는 도중에 윈도우 폼에서 listBox컨트롤을 사용하였는데, TcpListener를 사용하는 Thread 안에서 Handler 클래스를 호출하면 Handler 클래스 내에 등록한 이벤트가 발생하여 윈도우 폼에 있는 listBox에 메시지를 출력하는 경우였습니다. 컴파일을 한 경우 정상적으로 실행되지만 디버깅모드에 들어가면 저 메시지가 출력 되더군요.

  네이년을 뒤져보니 다음 해결방법을 찾았습니다. 그 해결방법에 따라 소스를 아래와 같이 변경하였더니 정상적으로 디버깅 됩니다. 방법은 delegate를 선언하여 다르 스레드에서 Control을 호출하는경우 Invoke로 그 함수를 다시 호출하는 거죠. 아래 방법을 보시면 도움이 되실겁니다.

#. 방법.
public partial class FTPServerForm : Form
{
        //System.InvalidOperationException처리를 위한 delegate 선언.
        delegate void SetMessageHandler(int nID, string strMessage);
        .
        .
        .
        .

       //delegate를 사용하여 Control의 InvokeRequired속성이 true일 경우
     //Form에서 Invoke 함수로 해당 함수를 다시 호출.

        void FtpServerMessageHandler_Message(int nID, string strMessage)
        {
            if (this.m_listBoxMessages.InvokeRequired)
          {
                SetMessageHandler message = new SetMessageHandler(FtpServerMessageHandler_Message);
                this.Invoke(message, new object[] { nID, strMessage });
            }
            else
            {
                //실제 listBox에서 출력되는 부분.
                .
                .
                .
                .
             }
        }
}


※. 꼭 같은 경우는 아니지만 크로스 스레드 작업 시 해당 윈폼의 생성자에다가 CheckForIllegalCrossThreadCalls = false;를 넣어 줘도 되는 경우가 있습니다.

Posted by 쿵캉켕