串口异步读取使用Base Stream

Serial Port Asynchronous Read Using Base Stream

我发现 C# 串口实现在涉及到 datarecieved 事件时可能非常不稳定,所以我决定使用底层 stream 实现我自己的异步读取。我实现了一个连续的读取循环,我希望它会由于递归而导致堆栈溢出,但由于某种原因它没有。这是代码:

SerialPort port = new SerialPort("COM0");
Stream bar = port.BaseStream;
Action foo = null;
foo = () =>
{
     byte[] buf = new byte[256];
     AsyncCallback callback = ar =>
     {
         int bytesRead = bar.EndRead(ar);
         //call event sending recieved bytes to main program
         foo();
     };
     bar.BeginRead(buf, 0, 8, callback, null);
};
foo();

我怀疑对 foo 的递归调用会不断生成新的堆栈帧,直到系统崩溃,但显然情况并非如此。

所以我的问题是,为什么对 foo 的递归调用不会导致堆栈溢出?

这段代码中没有递归。 C# 编译器将 lambda 表达式重写为 class 和 unspeakable namebuf 变量成为 class 的一个字段。如果您在程序集上使用 ildasm.exe ,您可以看到它回来, class 名称将类似于 <>c__DisplayClass.

回调在线程池线程上运行,在异步读取完成时启动。 "recursive" 调用 foo() 再次调用 BeginRead() 并且 tp 线程终止。

没有明显的理由说明这段代码比 DataReceived 事件更好,底层管道是相同的。