서버 클라이언트 공부하면서 클라이언트에서 서버에 메세지를 보내고 보낸 메세지를 확인하려는데 

메세지는 정상적으로 수신하지만 textbox에 접근을 하지 못하는 문제가 있었다.


그래서 검색해보니 통신할때에는 다른 스레드를 이용하기때문에 기존 UI 스레드에 접근하지 못하던 것이었다.

(여기서 말하는 UI스레드 - UI 컨트롤을 생성하고 이 컨트롤의 핸들을 소유한 스레드)



기존에는 아래와 같이 UI스레드에서 자기자신을 포인터로 넘겨주고

1
2
3
4
5
6
7
public static MainWindow getWindow
{
    get
    {
        return g_Main;
    }
}
cs

에코서버에서 수신한 메세지를 textbox(이름이 Console)에 추가하는 것이었는데 스레드가 달라서 접근하지 못했다.

1
MainWindow.getWindow.Console.Text += text;
cs



그래서 아래처럼 Dispatcher.Invoke를 사용하여 다른 스레드에서의 접근이 가능하도록 하였다.

1
2
3
4
5
6
7
8
9
public void addText(string text)
{
    this.Dispatcher.Invoke((Action)(() =>
    {
        string myText = Console.Text;
        myText += text;
        Console.Text = myText;
    }));
}
cs

에코서버에서는 아래와 같이 바꿔줬다.

1
MainWindow.getWindow.addText(text);
cs



Dispatcher.Invoke 메서드

https://msdn.microsoft.com/ko-kr/library/system.windows.threading.dispatcher.invoke(v=vs.110).aspx



쉽게 말하자면 Dispatcher.Invoke를 사용하면 다른 스레드에서 호출을 받더라도 그 스레드에서 실행하지않고

UI 스레드로 넘어와 여기서 작업을 실행한다고 생각하면 된다.


Action은 뒤에 있는 함수를 실행하겠다는건데. 

여기서는 기존의 생성한 함수를 쓰지않고 람다식을 이용해 새로 함수를 생성하여 바로 실행한 것이다.



검색하다가 발견한 사이트인데 여기 굉장히 정리가 잘 되어있다. 더 많은 내용은 여기를 참고하면 좋을듯.

http://www.csharpstudy.com/Threads/uithread.aspx

Posted by misty_
,