LINQPad和未处理异常

3

我正在尝试使用以下C#语句崩溃LINQPad4:

new Thread(() => new Thread(() => { throw new Exception(); }).Start()).Start();

出现未处理异常对话框,但进程不会停止。我猜想像所有UnhandledThreadExceptions一样,IsTerminating = true...它是如何防止进程死亡的?


2
对不起,我无法自控。你为什么要这样做? - Kirk Woll
哈哈。正在尝试在我的一个应用程序中添加相同的功能。 :P - hb.
1
我知道了。用户确实会故意尝试崩溃程序。-) - sgmoore
只有在有用的时候才使用 :p - hb.
不要试图抛出StackOverflowException - CLR会阻止你捕获它! - Joe Albahari
2个回答

5

它还有一个全局异常处理程序,用于所有非UI线程异常,类似于Main方法中的以下内容:

AppDomain.CurrentDomain.UnhandledException += 
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

当然还有其他一些小事情需要做,通常情况下在Application.Run周围加上try/catch。
查看完整文章和详细信息请点击这里:C#教程 - 处理未处理的异常 编辑:hb. 尝试调试这个:;-)
using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            new Thread(() => new Thread(() => { throw new ApplicationException("Ciao"); }).Start()).Start();

            try
            {
                Application.Run(new Form1());
            }
            catch (Exception exc)
            {
                System.Diagnostics.Debug.WriteLine(exc.Message);
            }
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            // here catching Unhandled Exceptions
            System.Diagnostics.Debug.WriteLine(e.ExceptionObject.ToString());
        }
    }
}

但是未处理的线程异常总是会终止应用程序。LINQPad如何忽略这一部分? - hb.
它不是未处理的,而是在线程内未处理,但LINQPad可以正确处理它。 - Davide Piras
1
只是确保我理解得正确。这个可以用,但如果我创建另一个AppDomain,它会崩溃 - 对吗?(除非我将处理程序添加到那个AppDomain。) - hb.
1
LINQPad 的 app.config 包括 <legacyUnhandledExceptionPolicy enabled="1" /> - 这允许处理线程异常,而不会导致应用程序随后死亡。 - Joe Albahari

1

LINQPad似乎不仅执行其查询,而且还在其自己的AppDomain中加载其依赖项。如果您在应用程序中创建一个新的AppDomain,则可以友好地处理异常并以友好的方式重新加载/编译应用程序。

更有趣的是LINQPad如何处理其依赖项。显然,它们在加载到这些AppDomains时会被“影子复制”,因为我有一个自定义库,我能够“即时”对其进行更改,而LINQPad不会锁定该文件;相反,它似乎有一个FileSystemWatcher来查找文件的更改,卸载AppDomain,然后使用新的依赖项重新加载AppDomain。

在构建新库后应用程序中的“暂停”,然后通过智能感知使这些新添加的“方法”现在可用于脚本,表明LINQPad在处理可能导致崩溃的脚本和引用库时相当智能。

然而,如果你真的想玩一些有趣的东西,你总是可以使用System.Diagnostics.Debugger.Break()。如果你在LINQPad属性中关闭脚本的优化,你实际上可以调试到LINQPad进程中,将源代码放在Visual Studio调试器窗口中,设置断点,逐步执行,检查变量等,以便实际上“调试”在LINQPad中创建的代码片段。这是你脚本中的几行额外代码,但如果你在LINQPad中进行了一些重度脚本/测试,那么它绝对是值得的。

这仍然是我能找到的最好的工具之一,用于原型设计、单元测试和构建使用LINQ查询的C#代码,我可以轻松地将它们剪切并粘贴到应用程序中,并相对容易地确保它们的行为与观察到的一致。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接