2009-07-20 4 views
1
나는 서버에 대한 연결을 처리하고 클라이언트에서 데이터를 읽기 위해이 코드 조각을 사용하고

는 ReceiveMessage 방법은 BeginRead()를 호출 ,하지만 난 ObjectDisposedException 있어요.하여 TcpClient와는 NetworkStream 처리 문제

나는 스트림이 더 이상 필요하지 않을 때 솔루션을 stream.Dispose()를 호출하는 것으로 알고 있지만 실제로는 using 절의 사용을 유지할 수있는 솔루션을 찾고 있습니다.

감사

답변

3

여기에는 두 가지 가능성이 있습니다.

먼저이 비동기 프로세스를 수행하고 완료 될 때까지 차단하여 using 문을 보존 할 수 있습니다. 이 방법은 suggested by Ben M here입니다.

또는 using 문을 제거하고 클라이언트 변수를 직접 처분 할 수 있습니다. 컴파일러의 구문을 사용하는 것보다 더 복잡해 보일 수도 있지만, 현재 상황에서 활용하려고하는 비동기 동작을 유지할 수있는 이점을 제공하고 블록이 필요하지 않습니다. 그러나 변수를 저장하고 적절한 위치 (대개 끝 부분에있을 수도 있음)에서 직접 처리해야합니다. 단, 나중에 대리자가 호출되지 않을 경우를 대비하여 나중에 확인해야 할 수도 있습니다.

C#의 "using"문은 훌륭하지만 적절하지 않은 상황이 있으며, 비동기 동작을 유지해야하는 경우이 중 하나 일 수 있습니다.

2

당신은이 작업을 수행 할 수 있습니다

using (var client = _listener.EndAcceptTcpClient(ar)) 
{ 
    var clientStream = client.GetStream(); 

    using (var eh = new ManualResetEvent(false)) 
    { 
     // Get the request message 
     Messages.ReceiveMessage(clientStream, msg => 
      { 
       ProcessRequest(msg, clientStream); 
       eh.Set(); 
      }); 

     eh.WaitOne(); 
    } 
} 

하나주의 :이 재사용 할 수 있도록으로 ManualResetEvent를 저장하기 위해 (클래스 인스턴스) 아무 곳이나 분별이 있다면 이렇게 - 이후 이것들을 많이 만들거나 파괴하는 것은 약간의 피로가 될 수 있습니다.

또한 귀하의 게시물에서 설명한 동작에서 ReceiveMessage()가 비동기 작업이라고 가정합니다.

+0

ManualResetEvent는 IDisposable을 구현하므로이 패턴은 using 문으로 묶어야합니다. – Joe

+0

이것은 비동기 프로세스가 완료 될 때까지 기본적으로 블로킹하기 때문에 데이터의 비동기 처리를 "중단"합니다. 그것은 모든 상황에서 바람직하지 않을 수 있습니다. –

+0

주어진 제한 내에서 질문에 대답했습니다. :-) Joe는 ManualResetEvent를 사용하는 것에 대해(). –