在C#中手动取消固定byte []? [英] Manually unpinning a byte[] in C#?

查看:189
本文介绍了在C#中手动取消固定byte []?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,client.Connect.Receive似乎永久地固定了"byte []结果",从而导致内存从未被释放(因为它始终固定).我正在寻找一种方法告诉C#在this.OnReceive中使用它后,不再需要固定结果,但是我找不到内置函数或关键字来实现此目的.

In the following code, it seems that the client.Connect.Receive is pinning the "byte[] result" permanently, causing the memory to never be freed (as it's always pinned). I'm looking for a way to tell C# that result no-longer needs to be pinned after it's usage in this.OnReceive, but I can't find the built-in function or keyword to do this.

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

Does anyone know how I can get C# to unpin the byte[] array? (this is one of the sources of memory leaks in my C# application)

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

推荐答案

您可以自己固定/取消固定它,

You can pin/unpin it yourself, thusly:

//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个字节)) ).

But I'd personally be pretty surprised that client.Connect.Receive pins it "for all time". I've used it before (as I'm sure many have) and not run into an issue of this type. Alternately, if you're certain that's the problem, then instead of allocating a new result array each time, you can re-use one across the entire while loop (allocate it up where you start the listener, and only use lenbytes bytes each time).

这篇关于在C#中手动取消固定byte []?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆