串口异步读取使用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 name。 buf 变量成为 class 的一个字段。如果您在程序集上使用 ildasm.exe ,您可以看到它回来, class 名称将类似于 <>c__DisplayClass
.
回调在线程池线程上运行,在异步读取完成时启动。 "recursive" 调用 foo() 再次调用 BeginRead() 并且 tp 线程终止。
没有明显的理由说明这段代码比 DataReceived 事件更好,底层管道是相同的。
我发现 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 name。 buf 变量成为 class 的一个字段。如果您在程序集上使用 ildasm.exe ,您可以看到它回来, class 名称将类似于 <>c__DisplayClass
.
回调在线程池线程上运行,在异步读取完成时启动。 "recursive" 调用 foo() 再次调用 BeginRead() 并且 tp 线程终止。
没有明显的理由说明这段代码比 DataReceived 事件更好,底层管道是相同的。