TcpClient and NetworkStream dispose problem

倖福魔咒の 提交于 2019-12-08 08:45:46

问题


I'm using this piece of code to process a connection to a server and read data from the client

using(var client = _listener.EndAcceptTcpClient(ar))
{
        var clientStream = client.GetStream();
        // Get the request message 
        Messages.ReceiveMessage(clientStream, msg => ProcessRequest(msg, clientStream));
}

Now, the ReceiveMessage method calls BeginRead() on the Stream passed as a parameter, but I'm getting an ObjectDisposedException.

I know that a solution is to call stream.Dispose() when I don't need the Stream anymore, but I'm really looking for a solution where I can maintain the use of the using clause.

Thanks


回答1:


There are two possibilities here.

First, you could take this asynchronous process and block until it completes, allowing you to preserve the using statement. This is the approach suggested by Ben M here.

Alternatively, you can remove the using statement, and dispose of the client variable yourself. This may seem more cumbersome than using the compiler's syntax for using, but it does provide the advantage of allowing you to maintain the asynchronous behavior your currently are trying to take advantage of in this situation, and eliminates the need for blocks. However, this will require you to store the variable, and dispose of it yourself in an appropriate place (possibly at the end of your delegate, but that also probably requires checking it later, just in case the delegate is never called).

The "using" statement in C# is great, but there are situations where it is not appropriate, and this may be one of them (if you need to preserve the asyncrhonous behavior).




回答2:


You can do this:

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();
    }
}

One caveat: if there's anywhere sensible (a class instance) to store the ManualResetEvent, so that it can be reused, do so -- since creating/destroying lots of these can be a bit piggy.

Also note that I'm assuming from the behavior you describe in your post that ReceiveMessage() is an asynchronous operation.



来源:https://stackoverflow.com/questions/1155191/tcpclient-and-networkstream-dispose-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!