I'm trying to use the following to continuously read data from a 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(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);
}
This leaks memory with an ever-increasing number of the following objects:
- ManualResetEvent
- Microsoft.Win32.SafeHandles.SafeWaitHandle
- ThreadPoolBoundHandleOverlapped
- OverlappedData
- SerialStream+SerialStreamAsyncResult
The objects persist even after a garbage collection pass.
The sample above is a minimal reproducible example. I've taken out the "do something with data" because the problem occurs with or without any data handling at that point.
The Thread.Sleep in the while loop only slows down memory consumption. I've left it out so that it clearly shows the problem. The above sample will consume approximately 650mb in 20 seconds on my machine.
The problem occurs in both .NET Core 3.1 and .NET Framework 4.8.
I'm sure I'm doing something wrong, I just can't see what it is at this point.