异步I/O带未捕获异常的地方
问题描述:
我正在开发基于控制台的.NET应用程序(使用单声道)。我正在使用异步I/O(Begin/EndReceive)。异步I/O带未捕获异常的地方
我在一个回调链的中间几层深,如果抛出一个异常,它不会被困在任何地方(让它出现到控制台是我所期望的,因为目前没有异常处理)。
但是,当我在发生堆栈跟踪时发现堆栈跟踪时,堆栈并未显示它已返回到初始执行点。
我试过AppDomain.UnhandledException技巧,但在这种情况下不起作用。
System.ArgumentOutOfRangeException: Argument is out of range.
Parameter name: size
at System.Net.Sockets.Socket.BeginReceive (System.Byte[] buffer, Int32 offset, Int32 size, SocketFlags socket_flags, System.AsyncCallback callback, System.Object state) [0x00000]
at MyClass+State.BeginReceive() [0x00000]
答
我相信异步调用过程中产生的误差应在调用EndAction方法(在你的情况EndReceive)被抛出。至少,这是我使用CLR(MSFT)实现的经验,而Mono应该做同样的事情,尽管它可能在这里稍微有点bug(尽管如此,不过这可能性不大)。如果你在Visual Studio中,我建议你打开捕获所有异常的选项(i)在Debug> Exceptions菜单中) - 也许在你使用的任何IDE中都有类似的选项?
答
从堆栈的外观来看,异常是在BeginReceive中引发的,因此根本没有启动特定的I/O操作。
线程池线程上的未处理异常的默认行为(从CLR2.0开始)是终止进程,所以如果你没有看到这一点,那么某种东西正在捕捉异常。
答
使用微软的.NET通常在异步调用期间引发的大多数异常在异步回调方法中引发,除少数情况外。为了处理剩下的事情,我通常会设置一个超时回调方法。
在异步调用期间,是的。您可以使用Socket.EndReceive(IAsyncResult,SocketError)来检索发生的SocketError。但在这种情况下,BeginReceive从不启动,因为我的'size'参数超出范围。 – osi 2009-02-20 23:12:47
对不起,没有注意到。在这种情况下,您是否尝试过在CLR下的Windows上运行代码?这将有助于缩小它至少是否是单声道问题。 – Noldorin 2009-02-20 23:42:04