3

次のコードでは、client.Connect.Receive が "byte[] 結果" を永久にピン留めしているように見えますが、メモリは解放されません (常にピン留めされているため)。this.OnReceive での使用後に結果を固定する必要がなくなったことを C# に伝える方法を探していますが、これを行うための組み込み関数またはキーワードが見つかりません。

C# で byte[] 配列の固定を解除する方法を知っている人はいますか? (これは、私の C# アプリケーションでのメモリ リークの原因の 1 つです)

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();
4

1 に答える 1

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 ループ全体で 1 つを再利用できます (リスナーを開始する場所に割り当て、毎回 lenbytes バイトのみを使用します)。 )。

于 2011-01-28T16:38:57.960 に答える