我发现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
不会导致堆栈溢出?
答案 0 :(得分:2)
此代码中没有递归。 C#编译器将lambda表达式重写为具有unspeakable name的类。 buf 变量成为该类的字段。如果在程序集上使用ildasm.exe,则可以看到它,类名称将类似于<>c__DisplayClass
。
回调在线程池线程上运行,在异步读取完成时启动。 &#34;递归&#34;调用foo()再次调用BeginRead()并且tp线程终止。
没有明显的理由说明为什么这个代码比DataReceived事件更好,底层管道是相同的。