Mik*_*ain 11 .net stack-overflow appdomain
我的印象是AppDomains彼此隔离.似乎在StackOverException的情况下,情况并非如此.
为了演示这个问题,我创建了一个简单的控制台应用程序,其唯一目的是生成一个新的AppDomain,我在其中加载一个非常简单的程序集并调用其中一个方法.此方法恰好抛出StackOverflowException.这导致我的控制台应用程序毫不客气地终止.
我希望的行为是"子"AppDomain崩溃并在这样的异常上刻录,但是保持我的控制台应用程序在"父"AppDomain中运行,没有受到损坏.
这可能吗?
更新:这是一些代码.两个异常处理程序都没有被命中.
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
// create app domain
var domain = AppDomain.CreateDomain("MyDomain");
// create a component
var component = (MyComponent)domain.CreateInstanceAndUnwrap(
"AppDomainMonitor.Component",
typeof(MyComponent).FullName);
// create a thread from a method on this component
var thread = new Thread(component.CauseStackOverflow);
// start the thread
thread.Start();
Console.ReadKey();
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// never hit
}
}
public class MyComponent : MarshalByRefObject
{
public void CauseStackOverflow()
{
try
{
Infinite();
}
catch (Exception ex)
{
// never hit
}
}
void Infinite()
{
Infinite();
}
}
Run Code Online (Sandbox Code Playgroud)
AppDomains之间仅隔离了托管内存.如果一个线程在任何AppDomain中抛出异常,这将导致整个应用程序崩溃.
我认为最好的解决方案是确保在每个线程(或线程池工作项)上正确处理所有异常.
然而,有一个hack包括在App.Config文件中应用此配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
自.Net 2.0以来,未处理的异常会导致进程崩溃,但您可以使用此技巧恢复旧策略.
我会谨慎地使用它,因为通常最好让进程崩溃而不是静默失败.您可以在AppDomain.UnhandledException中添加跟踪,以便在发生未处理的异常时得到通知并适当地处理它们.
编辑
你是对的StackOveflowException,因为.Net 2.0这个异常不能由用户代码处理.(参见msdn中本页的备注部分).
有一种方法可以通过创建自定义CLR主机来覆盖它,但这似乎是一个疯狂的事情.我想你将不得不忍受它,或者你可以创建子进程而不是AppDomain,如果你真的需要这种容错.
| 归档时间: |
|
| 查看次数: |
1345 次 |
| 最近记录: |