포스트

UI 멈춤 없이 TCP 통신하는 방법 (TcpClient 비동기 처리)

Async Tcp

UI 멈춤 없이 TCP 통신하는 방법 (TcpClient 비동기 처리)

보통 C#에서 TcpClient를 사용할 때 Read()Write() 같은 동기 함수는
UI 스레드를 블로킹시키기 때문에 버튼 클릭, 리스트 갱신 등이 멈춰버릴 수 있습니다.
이를 방지하려면 반드시 비동기 통신 (async/awiat)을 사용해야 합니다.

UI가 멈추는 잘못된 예시

1
2
3
4
// WinForms / WPF 버튼 클릭 이벤트 안에서
var stream = client.GetStream();
byte[] buffer = new byte[1024];
int length = stream.Read(buffer, 0, buffer.Length);  // ❌ 이 줄에서 UI 멈춤 발생

해결방법: 비동기 방식 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private async Task ReceiveAsync(TcpClient client)
{
    var stream = client.GetStream();
    byte[] buffer = new byte[1024];

    while (client.Connected)
    {
        int byteCount = await stream.ReadAsync(buffer, 0, buffer.Length);
        if (byteCount > 0)
        {
            string msg = Encoding.UTF8.GetString(buffer, 0, byteCount);
            Console.WriteLine("서버 메시지: " + msg);
            // UI 업데이트는 Dispatcher.Invoke(...) 또는 InvokeRequired 사용
        }
    }
}

WPF에서 UI 안전하게 업데이트 하는 방법

1
2
3
4
Application.Current.Dispatcher.Invoke(() =>
{
    MyTextBox.Text += "수신: " + msg + "\n";
});

또는 MVVM 구조라면 ObservableCollection + INotifyPropertyChanged 로 바인딩 처리 가능.

메세지 보내기도 비동기로

1
2
3
4
5
6
private async Task SendAsync(TcpClient client, string message)
{
    var stream = client.GetStream();
    byte[] data = Encoding.UTF8.GetBytes(message);
    await stream.WriteAsync(data, 0, data.Length);
}

정리

항목동기 방식비동기 방식
UI 멈춤발생함없음
코드 길이짧음조금 더 길지만 안전
추천 용도콘솔, 테스트WPF, Winforms 등 UI 앱

마무리

TCP 통신을 UI 와 함께 사용하는 경우
반드시 ReadAsync, WriteAsync 같은 비동기 방식으로 구현하고,
UI 업데이트는 Dispatcher 를 통해 안전하게 처리해야 합니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.