How to properly handle incoming protobuf message with a NetworkStream?

∥☆過路亽.° 提交于 2019-12-11 04:24:17

问题


Using TCPClient's NetworkStream and protobuf-net I send and receive protobuf messages via TCP. Receiving is done with the following method that runs in an own thread:

private void HandleClientComm()
{
    using (NetworkStream stream = m_Stream)
    {
        object o;
        while (true)
        {
            if (stream.CanRead && stream.DataAvailable)
            {
                o = null;
                if (Serializer.NonGeneric.TryDeserializeWithLengthPrefix(stream, PrefixStyle.Base128, Utilities.CommunicationHelper.resolver, out o))
                {
                    if (o != null)
                    {
                        //Do something with the incoming protobuf object
                    }
                }
                Thread.Sleep(1);
            }
        }
    }   
}

This works fine, but I have a problem with the garbage collection. It seems like old protobuf objects are still kept in the memory. Large message lead to System.OutOfMemoryExceptions after a while.

Explicitly calling GC.Collect() before sleeping fixes this problem. But it obviously slows down everything. How do I handle this properly?


回答1:


protobuf-net itself isn't going to keep hold of the old messages - indeed, if it was doing that, the GC.Collect wouldn't have helped.

The first thing I can see is that the hot loop waiting on DataAvailable is really expensive; that could perhaps be interfering with GC. The second thing I can see is that you can probably release the object at o before sleeping; as a random thing to try, perhaps:

using (NetworkStream stream = m_Stream)
{
    object o;
    while (Serializer.NonGeneric.TryDeserializeWithLengthPrefix(
        stream, PrefixStyle.Base128,
        Utilities.CommunicationHelper.resolver, out o))
    {
        if (o != null)
        {
            //TODO: Do something with the incoming protobuf object

            // clear o, just to give GC the very best chance while we sleep
            o = null;
        }
        Thread.Sleep(1); // <=== not sure why you want to sleep here, btw
    }
}


来源:https://stackoverflow.com/questions/16957210/how-to-properly-handle-incoming-protobuf-message-with-a-networkstream

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