2011-09-18 3 views
0

C#이 이벤트 중심 프로그래밍 언어라고 생각했습니다.메시지 또는 클라이언트 연결을 대기 중일 때 while (true) 루프를 반복하는 대신? (TcpClient C#)

일의이 유형은 나에게 오히려 혼란과 비효율적 인 것 같다

tcpListener.Start(); 

while (true) 
{ 
    TcpClient client = this.tcpListener.AcceptTcpClient(); 

    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication)); 

    clientThread.Start(client); 
} 

가 나는 또한 새 메시지가 도착하기를 기다릴 때 물건의 같은 종류의 일을해야합니다. 분명히 이러한 함수는 스레드 내에 포함됩니다.

무한 루프와 CPU 사이클 낭비가 발생하지 않는 더 좋은 방법은 없을까요? 이벤트? 알림? 어떤 것? 그렇지 않다면 Thread.Sleep을 수행하는 것이 좋지 않은가? 그래서 거의 자주 처리되지 않습니까?

+0

비동기 프로그래밍에 대해 알고 계십니까? – Marlon

+3

불필요한 CPU 사이클이 무슨 뜻인지 확실치 않습니다. 'AcceptTcpClient'는 연결을 얻을 때까지 현재 쓰레드를 차단하고, 차단 된 동안 CPU 사이클을 사용하지 않습니다. –

답변

1

게시 한 방법에는 아무런 문제가 없습니다. 언급 한 것처럼 낭비되는 CPU 사이클도 없습니다. TcpClient.AcceptTcpClient()은 클라이언트가 연결될 때까지 스레드를 차단합니다. 즉 CPU주기를 모두 차지하지 않습니다. 따라서 루프가 실제로 반복되는 유일한 시간은 클라이언트가 연결될 때입니다.

물론 루프를 종료하고 연결을 수신 대기하는 방법을 원한다면 while (true) 이외의 다른 것을 사용하는 것이 좋습니다.하지만 그 또 다른 주제입니다. 간단히 말해서 이것은 연결을 수락하는 좋은 방법이며 Thread.Sleep을 여기에 넣을 목적이 없습니다.

0

실제로 소켓에 대한 IO 작업을 처리하는 세 가지 방법이 있습니다. 첫 번째 방법은 차단 기능을 사용하는 것과 같습니다. 그들은 클라이언트 소켓을 처리하는 데 보통 사용됩니다. 클라이언트가 대부분의 시간을 직접 예상하고 응답하기 때문에 (따라서 블로킹 읽기를 사용할 수 있습니다)

다른 소켓 핸들러의 경우 두 비동기 차단) 모델.

첫 번째 모델은 사용할 가장 쉬운 모델입니다. Begin/End 메서드 이름과 Begin 메서드의 반환 값 IAsyncResult에 의해 인식됩니다. 무언가가 발생했을 때 호출 될 Begin 메서드에 콜백 (함수 포인터)을 전달합니다. 예를 들어 BeginReceive을 살펴보십시오.

두 번째 비동기 모델은 Windows IO 모델 (IO Completion Ports)과 비슷합니다. 또한 .NET의 최신 모델이기 때문에 최상의 성능을 제공해야합니다. SocketAsyncEventArgs 개체는 동작을 제어하는 ​​데 사용됩니다 (작업이 완료 될 때 호출 할 메서드와 동일). 또한 작업을 직접 완료 할 수 있고 콜백 메서드가 호출되지 않는다는 사실을 알고 있어야합니다. RecieveAsync에 대해 자세히 알아보십시오.

관련 문제