C# SerialPort SerialStream读取循环中内存泄漏

C# SerialPort SerialStream读取循环中内存泄漏,c#,serial-port,C#,Serial Port,我尝试使用以下方法从串行端口连续读取数据: var serialPort = new SerialPort("COM7", 38400, Parity.None, 8, StopBits.One); var buffer = new byte[256]; Action read = null; AsyncCallback callback = delegate (IAsyncResult ar) { int len = serialPort.BaseStream.EndRead(a

我尝试使用以下方法从串行端口连续读取数据:

var serialPort = new SerialPort("COM7", 38400, Parity.None, 8, StopBits.One);

var buffer = new byte[256];

Action read = null;

AsyncCallback callback = delegate (IAsyncResult ar)
{
    int len = serialPort.BaseStream.EndRead(ar);

    // do something with data

    read();
};

read = delegate
{
    serialPort.BaseStream.BeginRead(buffer, 0, buffer.Length, callback, null);
};

serialPort.Open();

while (true)
{
    read();

    //Thread.Sleep(100);
}
这会泄漏内存,并导致以下对象数量不断增加:

  • 手动复位事件
  • Microsoft.Win32.SafeHandles.SafeWaitHandle
  • ThreadPoolBoundHandle重叠
  • 重叠数据
  • SerialStream+SerialStreamAsyncResult
即使在垃圾收集过程之后,这些对象仍然存在

上述样品是一个最小的可重复性示例。我去掉了“对数据做点什么”,因为无论是否处理数据,问题都会出现

while循环中的
线程.Sleep
只会降低内存消耗。我把它漏掉了,以便清楚地显示问题所在。在我的机器上,上面的示例将在20秒内消耗大约650mb

问题出现在.NET Core 3.1和.NET Framework 4.8中

我肯定我做错了什么,我只是看不出这是什么

这将以不断增加的速度泄漏内存

很简单,因为在现有操作完成之前,您正在无限循环
beginhead
操作:

while (true)
{
    read(); // <-- this delegate calls `BeginRead` thus starting ANOTHER verlapped read operation

    //Thread.Sleep(100);
}
您的回调正在做正确的事情,确保只有在前一个完成后才开始另一个重叠读取操作:

AsyncCallback callback = delegate (IAsyncResult ar)
{
    int len = serialPort.BaseStream.EndRead(ar);

    // do something with data

    read(); // <--- correctly initiates another read since the existing is complete
};

AsyncCallback=delegate(IAsyncResult ar)
{
int len=serialPort.BaseStream.EndRead(ar);
//处理数据

读()59449谢谢你的接受
AsyncCallback callback = delegate (IAsyncResult ar)
{
    int len = serialPort.BaseStream.EndRead(ar);

    // do something with data

    read(); // <--- correctly initiates another read since the existing is complete
};