는 ReceiveMessage 방법은 BeginRead()
를 호출 ,하지만 난 ObjectDisposedException 있어요.하여 TcpClient와는 NetworkStream 처리 문제
나는 스트림이 더 이상 필요하지 않을 때 솔루션을 stream.Dispose()를 호출하는 것으로 알고 있지만 실제로는 using
절의 사용을 유지할 수있는 솔루션을 찾고 있습니다.
감사
는 ReceiveMessage 방법은 BeginRead()
를 호출 ,하지만 난 ObjectDisposedException 있어요.하여 TcpClient와는 NetworkStream 처리 문제
나는 스트림이 더 이상 필요하지 않을 때 솔루션을 stream.Dispose()를 호출하는 것으로 알고 있지만 실제로는 using
절의 사용을 유지할 수있는 솔루션을 찾고 있습니다.
감사
여기에는 두 가지 가능성이 있습니다.
먼저이 비동기 프로세스를 수행하고 완료 될 때까지 차단하여 using 문을 보존 할 수 있습니다. 이 방법은 suggested by Ben M here입니다.
또는 using 문을 제거하고 클라이언트 변수를 직접 처분 할 수 있습니다. 컴파일러의 구문을 사용하는 것보다 더 복잡해 보일 수도 있지만, 현재 상황에서 활용하려고하는 비동기 동작을 유지할 수있는 이점을 제공하고 블록이 필요하지 않습니다. 그러나 변수를 저장하고 적절한 위치 (대개 끝 부분에있을 수도 있음)에서 직접 처리해야합니다. 단, 나중에 대리자가 호출되지 않을 경우를 대비하여 나중에 확인해야 할 수도 있습니다.
C#의 "using"문은 훌륭하지만 적절하지 않은 상황이 있으며, 비동기 동작을 유지해야하는 경우이 중 하나 일 수 있습니다.
당신은이 작업을 수행 할 수 있습니다
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()가 비동기 작업이라고 가정합니다.
ManualResetEvent는 IDisposable을 구현하므로이 패턴은 using 문으로 묶어야합니다. – Joe
이것은 비동기 프로세스가 완료 될 때까지 기본적으로 블로킹하기 때문에 데이터의 비동기 처리를 "중단"합니다. 그것은 모든 상황에서 바람직하지 않을 수 있습니다. –
주어진 제한 내에서 질문에 대답했습니다. :-) Joe는 ManualResetEvent를 사용하는 것에 대해(). –