未处理的异常在儿童的AppDomain可以从崩溃的主要过程pvented $ P $? [英] Can Unhandled Exceptions in Child AppDomains be prevented from crashing the main process?

查看:222
本文介绍了未处理的异常在儿童的AppDomain可以从崩溃的主要过程pvented $ P $?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个小插件库,它使用应用程序域隔离使用.NET Framework 4.0的插件。因此,code表示云中的每个插件是在我的掌握。当未处理的异常引发的插件之一,我观察的结果,是一种鱼龙混杂。它们如下

I'm writing a small plugins library which uses app domains to isolate plugins using .Net framework 4.0. Hence the code that goes in each plugin is out of my control. When an unhandled exception is raised in one of the plugins, I have observed the results to be kind of a mixed bag. They are as follows.

在未处理的异常被抛出插件的主线,主要可插入应用程序调用该插件的执行方法是能够赶上和清洁处理。有没有问题。然而,

When the unhandled exception gets thrown in the plugin's main thread, the main pluggable app calling the plugin's execute method is able to catch and handle it cleanly. No problems there. However,

  1. 如果该插件开始在插件的执行方法的消息循环的一个WinForms基础的应用程序和未处理的异常被抛出在WinForm应用程序(即形式),那么可插入应用程序,则仅可捕获的异常的从Visual Studio调试器中运行。否则(当VS之外调用)的主要可插拔的应用程序崩溃随着插件。

  1. If the plugin starts a message loop for a WinForms based app in the plugin's Execute method and an unhandled exception gets thrown in the WinForm application (i.e. in a form) then the pluggable app can only catch the exception if its running from inside visual studio debugger. Otherwise (when invoked outside VS) the main pluggable app crashes along with the plugins.

如果未处理的异常被抛出由插件的Execute方法催生了一个单独的线程,然后可插入应用程序有没有机会捕捉异常和崩溃。

If the unhandled exception is thrown in a separate thread spawned by the plugin's Execute method, then the pluggable app has no chance of catching the exception and it crashes.

我创建了一个简单的VS 2010项目以模拟在下面的链接这种行为。 <一href="http://www.mediafire.com/file/1af3q7tzl68cx1p/PluginExceptionTest.zip">http://www.mediafire.com/file/1af3q7tzl68cx1p/PluginExceptionTest.zip

I have created a simple VS 2010 project to simulate this behaviour at the link below. http://www.mediafire.com/file/1af3q7tzl68cx1p/PluginExceptionTest.zip

在它的可插入应用程序的主要方法看起来像这样

In it the main method in the pluggable app looks like this

namespace PluginExceptionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Press enter to load plugin");
            Console.ReadLine();

            Assembly entryAsm = Assembly.GetEntryAssembly();
            string assemblyFileName = Path.Combine(Path.GetDirectoryName(entryAsm.Location), "EvilPlugin.exe");


            AppDomainSetup domainSetup = new AppDomainSetup();
            AppDomain domain = AppDomain.CreateDomain("PluginDomain", null, domainSetup);
            PluginBase plugin = (PluginBase)domain.CreateInstanceFromAndUnwrap(assemblyFileName, "EvilPlugin.Plugin");

            Console.WriteLine("Plugin Loaded.");

            //SCENARIO 1: WinForms based plugin
            Console.WriteLine("Press Enter to execute winforms plugin. (Remember to click on the button in the form to raise exception)");
            Console.ReadLine();

            try
            {
                plugin.ExecuteWinApp();
            }
            catch (Exception)
            {
                //The exception is caught and this gets executed only when running in visual studio debugger. Else application exits. Why?
                Console.WriteLine("WinForms plugin exception caught. However same does not happen when run out of visual studio debugger. WHY?");
            }

            //SCENARIO 2: WinForms based plugin
            Console.WriteLine("Press Enter to execute threading plugin, wait for 3 seconds and the app will exit. How to prevent app from exiting due to this?");
            Console.ReadLine();
            try
            {
                plugin.ExecuteThread();
            }
            catch (Exception)
            {
                //This never gets executed as the exception is never caught. Application exits. Why?
                Console.WriteLine("WinForms plugin exception caught");
            }

            Console.ReadLine();
        }
    }
}

这是在code的插件项目。它继承了PluginBase类的可插入应用程序的项目上面。

This is the code for the plugin project. It inherits from the PluginBase class in the pluggable app project above.

namespace EvilPlugin
{
    public class Plugin:PluginBase
    {
        public Plugin():base()
        {

        }

        public override void ExecuteWinApp()
        {            
            Application.Run(new Form1());            
        }

        public override void ExecuteThread()
        {
            Thread t = new Thread(new ThreadStart(RaiseEx));           
            t.Start();
        }

        private void RaiseEx()
        {
            Thread.Sleep(3000);
            throw new Exception("Another Evil Exception in a seperate thread");
        }
    }
}

最后,这是从表格中的插件的code

Finally this is the code from the Form in the plugin

namespace EvilPlugin
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnException_Click(object sender, EventArgs e)
        {
            throw new Exception("Evil Exception");
        }
    }
}

如何prevent从退出的主要过程,由于两种情况(1和2)上述?

How can i prevent the main process from exiting due to the two scenarios (1 and 2) mentioned above?

在此先感谢。

推荐答案

有关处理的WinForms异常。您可以设置陷阱这样的ThreadExceptions在PluginBase类:

For handling WinForms exception. You could set "trap" for such ThreadExceptions in PluginBase class:

public abstract class PluginBase:MarshalByRefObject
{
    protected PluginBase()
    {
        System.Windows.Forms.Application.ThreadException +=
            (o, args) =>
            {
                throw new Exception("UntrappedThread Exception:" + args.Exception);
            };

    }

    public abstract void ExecuteWinApp();
    public abstract void ExecuteThread();
}

由于在默认情况下,它会告诉你例外窗口。但是,将得到的,如果提供这种处理器。

As by default, it will show you "The Exception Window". But will got to this handler if provided.

作为从其他线捕捉异常。不可能。你能做的最好是有一个关于异常被抛出通知。

As for catching exception from other thread. There is no way. The best you could do is have a notification about Exception being thrown.

    AppDomain domain = AppDomain.CreateDomain("PluginDomain", null, domainSetup);
    domain.UnhandledException +=
        (o, eventArgs) =>
            {
                Console.WriteLine("Exception was caught from other AppDomain: " + eventArgs.ExceptionObject);
                Console.WriteLine("CLR is terminating?: " + eventArgs.IsTerminating);
            };

这篇关于未处理的异常在儿童的AppDomain可以从崩溃的主要过程pvented $ P $?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆