AppDomain中,处理异常异常、AppDomain

2023-09-02 01:46:21 作者:此男值得擁有

我开发了大量应用程序,它由许多小插件/应用程序。

I am developing a large application which consists of many smaller plugins/applications.

他们没有大到足以成为一个完整的过程,但太小,无法在一个线程中运行,在一个过程中,随着我想它基于一个插件,基础有。 如果该插件的更新版本可用,应卸载,更新和重新启动。

They are not big enough to be a full process, but are too small to be run in a thread, under one process, along with that I want to have it based on a plugin-basis. If a newer version of that plugin is available it should be unloaded, updated and started again.

在我寻找一个解决方案,我可以进行的跨魔语AppDomain中,我引用:

During my search for a solution I can accross the magic word AppDomain, and I quote:

使用应用程序域隔离可能搞垮一个任务   处理。如果在AppDomain中对正在执行任务的状态变为   不稳定的,在AppDomain可以在不影响该过程被卸载。   这在一个进程必须运行长时间没有很重要   重新启动。您还可以使用应用程序域隔离任务   不能共享数据。

"Use application domains to isolate tasks that might bring down a process. If the state of the AppDomain that's executing a task becomes unstable, the AppDomain can be unloaded without affecting the process. This is important when a process must run for long periods without restarting. You can also use application domains to isolate tasks that should not share data."

因此​​,这正是我想要的。不过,我想他们的状态不稳定是一个不同的观点不是我的。我想到一个问题,即插件之一抛出异常,不管是什么原因的。我想是被逮住,通过电子邮件发送,卸载和重新启动(如果可能)。

Thus that is exactly what I want. However, I guess their 'State becomes unstable' is a different point of view than mine. I am thinking of a problem where one of the plugins throws an exception, for whatever reason. I would like that be catched, e-mailed, unloaded and restart (if possible).

所以,我创建启动后,查找所有.dll文件在其文件夹中的应用程序。检查如果DLL包含一个插件。创建该插件的新的AppDomain,一旦一切都装好了开始的每个插件。 (每个插件可以由多个线程,共存愉快旁边ECH等)。

So I created an application that starts up, looks for all .dll's in its folder. Checks if the dll consists of a plugin. Creates a new AppDomain for that plugin, and once everything is loaded it will start each plugin. (Where each plugin can consist of multiple threads, co-existing happily next to ech other).

所以,我还添加了一个时间在那里,5秒后火灾抛出一个新的异常();增加了UnhandledException事件上的AppDomain来处理它。但是,它逮住它,cathing后,仍然是崩溃的全过程,包括所有的额外孩子的AppDomain。

So I also added a time-out in there, that fires after 5seconds to throw a new Exception(); Added a UnhandledException event on the AppDomain to handle it. But, it catched it, and after cathing, still 'crashed' the whole process including all the extra child-AppDomains.

但它明确规定,在报价来隔离任务可能搞垮一个过程。所以我失去了一些东西重要?难道我的报价错误的看法?

But it clearly states in the quote 'to isolate tasks that "might" bring down a process'. So am I missing something vital? Is my view on the quote wrong?

推荐答案

由于.NET 2.0 未处理的异常崩溃这个过程。从AppDomain.UnhandledException事件文档:

Since .NET 2.0 unhandled exceptions crash the process. From AppDomain.UnhandledException event documentation:

此事件提供未捕获异常的通知。它允许   应用程序记录有关系统前的异常信息   默认的处理程序报告异常给用户和终止   应用

This event provides notification of uncaught exceptions. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application.

这同样适用AppDomain.FirstChanceException:

此事件是只是一个通知。处理此事件不处理   异常或以任何方式影响随后的异常处理。

java中应用异常处理的问题

This event is only a notification. Handling this event does not handle the exception or affect subsequent exception handling in any way.

您需要考虑你将如何处理异常的,就像你会做它在正常的应用程序。只是使用的AppDomain不会帮助。如果该异常没有得到应有的AppDomain中进行处理,将得到重新抛出在调用的AppDomain直到它得到处理或崩溃的过程。这是完全没有处理一些例外,不要让他们崩溃的过程。

You need to think about how you will handle exceptions just like you will do it in normal app. Just using AppDomains will not help. If the exception has not been handled within given AppDomain it will get rethrown in calling AppDomain until it either get handled or crashes the process. It is perfectly fine to handle some exceptions and don't let them crash your process.

的AppDomain是组件和存储器(不是线程)的逻辑容器。隔离的AppDomain意味着:

AppDomain is a logical container for assemblies and memory (not for threads). Isolation for AppDomain implies:

在域A创建的对象不能直接通过域B访问(无编组)。这使得域A无域B.影响任何这些对象将拥有域名被卸载时,都会自动删除,卸载。

Objects created in domain A can not be accessed directly by domain B (without marshaling). This allows for domain A to be unloaded without affecting anything in domain B. These objects will get automatically deleted when 'owning' domain gets unloaded.

组件可以自动的AppDomain卸载。这可以从流程管理的卸载DLL的唯一途径。这是为DLL的热插拔有用。

Assemblies can be automatically unloaded with AppDomain. This the only way you can unload managed dll from process. This is useful for DLL hot-swapping.

AppDomain的安全权限和配置可以从其他应用程序域隔离。当您加载不受信任的第三方code这会有所帮助。它也可以让你覆盖组件如何将被加载(版本绑定,阴影复制等)。

AppDomain security permissions and configuration can be isolated from other AppDomains. This can be helpful when you load untrusted third party code. It also lets you override how assemblies will be loaded (version binding, shadow copying etc).

使用,当你运行不受信任的第三方code AppDomain中是最常见的原因。或者你有非托管code和要承载CLR或需要dll的热插拔。我认为,在 CLR托管的情况下,您的可以保存你的进程崩溃时,第三方code抛出未处理的异常。

Most common reasons for using AppDomain is when you run untrusted third party code. Or you have unmanaged code and want to host CLR or need dll hot swapping. I think that in CLR hosting scenario you can save your process from crashing when thirdparty code throws unhandled exception.

另外,你可能想看看System.Addin或MEF 。