C# 如何使用NetworkStream正确处理传入的protobuf消息?

C# 如何使用NetworkStream正确处理传入的protobuf消息?,c#,garbage-collection,protobuf-net,networkstream,C#,Garbage Collection,Protobuf Net,Networkstream,使用TCPClient的NetworkStream和protobuf-net,我通过TCP发送和接收protobuf消息。通过在自己的线程中运行的以下方法完成接收: private void HandleClientComm() { using (NetworkStream stream = m_Stream) { object o; while (true) { if (stream.CanRead &am

使用TCPClient的NetworkStream和protobuf-net,我通过TCP发送和接收protobuf消息。通过在自己的线程中运行的以下方法完成接收:

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);
            }
        }
    }   
}
这很好,但我在垃圾收集方面有问题。似乎旧的protobuf对象仍保留在内存中。较大的消息会导致System.OutOfMemoryExceptions出现一段时间


在睡觉之前显式调用
GC.Collect()
,可以解决此问题。但它显然会减慢一切。我如何正确处理这件事

protobuf-net本身不会保存旧消息-事实上,如果它这样做,
GC.Collect
也不会有帮助

我能看到的第一件事是等待
DataAvailable
的热循环非常昂贵;这可能会干扰GC。我能看到的第二件事是,你可能可以在睡觉前在
o
释放物体;作为一种随机的尝试,也许:

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
    }
}
使用(NetworkStream=m_stream)
{
对象o;
while(Serializer.NonGeneric.TryDeserializeWithLengthPrefix(
流,前缀为style.Base128,
实用程序.CommunicationHelper.resolver,输出)
{
如果(o!=null)
{
//TODO:对传入的protobuf对象执行某些操作
//明白了,好让GC在我们睡觉的时候有最好的机会
o=零;
}

Thread.Sleep(1);//protobuf-net本身不会保存旧消息-事实上,如果它这样做,
GC.Collect
也不会有帮助

我能看到的第一件事是等待
DataAvailable
的热循环非常昂贵;这可能会干扰
GC
。我能看到的第二件事是,您可能可以在睡觉前在
o
释放对象;作为一种随机尝试,可能:

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
    }
}
使用(NetworkStream=m_stream)
{
对象o;
while(Serializer.NonGeneric.TryDeserializeWithLengthPrefix(
流,前缀为style.Base128,
实用程序.CommunicationHelper.resolver,输出)
{
如果(o!=null)
{
//TODO:对传入的protobuf对象执行某些操作
//明白了,好让GC在我们睡觉的时候有最好的机会
o=零;
}
睡眠(1)//