TcpClient和NetworkStream处理问题

发布于 2024-07-27 22:40:51 字数 506 浏览 7 评论 0原文

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

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

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

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

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万人眼中万个我 2024-08-03 22:40:54

您可以这样做:

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() 是异步操作。

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.

菩提树下叶撕阳。 2024-08-03 22:40:52

这里有两种可能性。

首先,您可以执行此异步进程并阻塞直至其完成,从而允许您保留 using 语句。 这是 Ben M 在此建议的方法。

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

C# 中的“using”语句很棒,但在某些情况下它并不合适,这可能就是其中之一(如果您需要保留异步行为)。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文