Visual Studio 2010不会停止在Socket.BeginReceive()回调中的未处理异常 - 为什么?

Tim*_*mwi 10 .net c# exception visual-studio-2010 asyncsocket

通常,在附加调试器时,即使"异常"对话框在"已抛出"列中没有异常类型的勾号,Visual Studio 2010也会在未处理的异常处停止.这里的关键字未处理; 所述对话框仅指处理的异常.

但是,在下面的最小示例中,Visual Studio 2010不会停止在我的异常,即使它作为第一次机会异常出现在立即窗口中:

编辑:我发布的第一个最小的例子是我收到的第一个答案修复,但不幸的是下面的例子仍然显示问题:

using System;
using System.Net.Sockets;

namespace SocketTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var listener = new TcpListener(8080);
            listener.Start();
            AsyncCallback accepter = null;
            accepter = ar =>
            {
                var socket = listener.EndAcceptSocket(ar);
                var buffer = new byte[65536];
                AsyncCallback receiver = null;
                receiver = ar2 =>
                {
                    var bytesRead = socket.EndReceive(ar2);
                    throw new InvalidOperationException();
                    socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, receiver, null);
                };
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, receiver, null);
                listener.BeginAcceptSocket(accepter, null);
            };
            listener.BeginAcceptSocket(accepter, null);

            Console.WriteLine("Feel free to connect to port 8080 now.");
            Console.ReadLine();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你运行它,通过运行连接到它telnet localhost 8080,然后在telnet中键入任何字符,希望你会看到我看到的:程序只是默默地中止.

为什么Visual Studio显然吞下了这个异常?我能否像通​​常那样让它在例外中突破?

(有趣的是,抛出BeginAcceptSocket回调内部确实会被捕获,正常线程中的异常Thread.Start也会被捕获.我只能通过抛出BeginReceive回调来重现问题.)

Rit*_*ton 13

由于您在异常设置中只看到"Thrown"复选框,因此我怀疑您在调试设置中启用了".Net Framework Source Stepping".如果启用"Just My Code"(禁用".Net Framework Source Stepping"),您应该在异常设置对话框中获得"User-Unhandled"和"Thrown"复选框,您还将在调试器中捕获异常.

屏幕截图O'胜利:

屏幕截图显示调试器按预期在异常处暂停


Han*_*ant 13

这是CLR第4版中的一个已知错误.反馈文章就在这里.可能的解决方法是将框架目标更改为3.5版.我只想引用反馈回复的相关部分:

我们调查了这个问题,并确定CLR v4.0中存在一个导致此问题的错误.该进程会抛出异常(例如,您可以使用catch处理程序捕获它),但调试器未正确通知未处理的异常.这导致进程似乎退出而没有来自调试器的任何关于发生的事情的指示.我们已经调查了潜在的修复,但是所有修复都有中断其他功能的风险.因为产品周期很晚,所以我们认为不解决这个问题更安全,并且有可能造成新的错误.我们将继续跟踪此问题,作为下一个发布周期的一部分.

该问题仅限于转义使用一些特定API调用创建线程的托管代码的异常:
new System.Threading.Timer()
ThreadPool.UnsafeQueueNativeOverloapped
ThreadPool.BindHandle
ThreadPool.RegisterWaitForSingleObject.

在这种特定情况下,它是RegisterWaitForSingleObject().