如何使用NetworkStream正确处理传入的protobuf消息? [英] How to properly handle incoming protobuf message with a NetworkStream?
问题描述
使用TCPClient的NetworkStream和protobuf-net,我通过TCP发送和接收protobuf消息.接收是通过在自己的线程中运行的以下方法完成的:
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);
}
}
}
}
这很好,但是我的垃圾回收有问题.似乎旧的protobuf对象仍保留在内存中.一段时间后,大消息导致System.OutOfMemoryExceptions.
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.
在睡眠之前显式调用GC.Collect()
可以解决此问题.但这显然会减慢一切.我该如何正确处理?
Explicitly calling GC.Collect()
before sleeping fixes this problem. But it obviously slows down everything. How do I handle this properly?
推荐答案
protobuf-net本身不会保留旧消息-确实,如果正在这样做,则GC.Collect
不会帮上忙.
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.
我首先看到的是,在DataAvailable
上等待的热循环确实非常昂贵.可能会干扰GC
.我看到的第二件事是,您可能可以在o
睡眠之前释放对象;作为随机尝试的东西,也许:
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
}
}
这篇关于如何使用NetworkStream正确处理传入的protobuf消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!