1

我正在使用这段代码来处理与服务器的连接并从客户端读取数据

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

现在,ReceiveMessage 方法调用BeginRead()作为参数传递的 Stream,但我得到了 ObjectDisposedException。

我知道一个解决方案是当我不再需要 Stream 时调用 stream.Dispose() ,但我真的在寻找一个可以保持using子句使用的解决方案。

谢谢

4

2 回答 2

3

这里有两种可能。

首先,您可以采用这个异步进程并阻塞直到它完成,从而允许您保留 using 语句。这是Ben M here 建议的方法。

或者,您可以删除 using 语句,并自己处理客户端变量。这可能看起来比使用编译器的语法更麻烦,但它确实提供了允许您在这种情况下保持当前尝试利用的异步行为的优势,并且消除了对块的需要。但是,这将要求您存储变量,并自己将其处理在适当的位置(可能在您的委托结束时,但这也可能需要稍后检查它,以防万一委托从未被调用)。

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).

于 2009-07-20T19:08:21.860 回答
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() 是异步操作。

于 2009-07-20T18:50:51.973 回答