手动取消固定C#中的byte []?

时间:2011-01-28 16:10:58

标签: c# memory-leaks pinning

在下面的代码中,似乎client.Connect.Receive永久地固定“byte []结果”,导致永远不会释放内存(因为它总是被固定)。我正在寻找一种方法来告诉C#,在使用它之后不再需要固定它.OnReceive,但我找不到内置函数或关键字来执行此操作。

有谁知道如何让C#取消固定byte []数组? (这是我的C#应用​​程序中的内存泄漏源之一)

this.m_TcpListener = new TcpListener(this.p_TcpEndPoint.Port);
this.m_TcpThread = new Thread(delegate()
{
    try
    {
        this.m_TcpListener.Start();
        while (this.p_Running)
        {
            TcpClient client = this.m_TcpListener.AcceptTcpClient();
            new Thread(() =>
                {
                    try
                    {
                        // Read the length header.
                        byte[] lenbytes = new byte[4];
                        int lbytesread = client.Client.Receive(lenbytes, 0, 4, SocketFlags.None);
                        if (lbytesread != 4) return; // drop this packet :(
                        int length = System.BitConverter.ToInt32(lenbytes, 0);
                        int r = 0;

                        // Read the actual data.
                        byte[] result = new byte[length];
                        while (r < length)
                        {
                            int bytes = client.Client.Receive(result, r, length - r, SocketFlags.None);
                            r += bytes;
                        }

                        Console.WriteLine("Received TCP packet from " + (client.Client.RemoteEndPoint as IPEndPoint).Address.ToString() + ".");
                        this.OnReceive(client.Client.RemoteEndPoint as IPEndPoint, result, length);
                    }
                    catch (SocketException)
                    {
                        // Do nothing.
                    }

                    client.Close();                                
                }).Start();
            //this.Log(LogType.DEBUG, "Received a message from " + from.ToString());
        }
    }
    catch (Exception e)
    {
        if (e is ThreadAbortException)
            return;
        Console.WriteLine(e.ToString());
        throw e;
    }
}
);
this.m_TcpThread.IsBackground = true;
this.m_TcpThread.Start();

1 个答案:

答案 0 :(得分:5)

你可以自己固定/取消固定:

//Pin it 
GCHandle myArrayHandle = GCHandle.Alloc(result,GCHandleType.Pinned);
//use array
while (r < length)
{
    int bytes = client.Client.Receive(result, r, length - r, SocketFlags.None);
    r += bytes;
}
//Unpin it
myArrayHandle.Free();

但是我个人非常惊讶于client.Connect.Receive将它“永远地”固定。我之前已经使用过它(因为我确信很多人都有)并没有遇到过这种类型的问题。或者,如果你确定这是问题所在,那么你不必每次都分配一个新的结果数组,而是可以在整个while循环中重复使用一个(在启动监听器的地方分配它,每次只使用lenbytes字节) )。