有很多主题涉及这个问题。但是我有一个问题。
我将程序集加载到新的AppDomain
中,如下所示:
public void Run()
{
//There's the problem.
//As Panos Rontogiannis mentioned the thread is created in default AppDomain
new Thread(RunApp).Start();
}
private void RunApp()
try
{
AppDomain.CreateDomain("domain name").ExecuteAssembly("path to assembly");
}
catch (Exception _e)
{
MessageBox.Show("Unhandled Exception.\n" + _e);
}
}
在加载程序集的Main方法中,我将处理程序订阅到UnhandledException
事件:
AppDomain.CurrentDomain.UnhandledException += handleException;
处理程序本身:
public static void handleException(object a_s, UnhandledExceptionEventArgs a_args)
{
var _e = (Exception)a_args.ExceptionObject;
//Static loger class method
Loger.WriteError(_e.GetType().ToString(), _e.Message, "default solution");
}
但是无论在加载的程序集中抛出异常,处理程序都不会涉及。我只在默认的AppDomain
(第一个try{} catch{}
)中捕获异常。
答案 0 :(得分:3)
最有可能的原因是,您无法在新AppDomain
中处理异常的原因是它不是从AppDomain
中创建的线程抛出的。从AppDomain.UnhandledException上的文档来看,这不是很简单。有趣的部分如下:
仅当线程的整个堆栈具有异常时才会处理异常 没有找到适用的异常处理程序就解开了,所以 第一个地方可以引发的事件是在应用程序域所在的地方 线程起源。
现在,如果执行抛出代码的线程是在主AppDomain
中创建的(就像控制台应用程序的主线程一样),那么您应该在主AppDomain
中添加一个处理程序。请注意,如果主AppDomain中未加载抛出异常的类型,.NET的Assembly Loader将尝试从应用程序的基目录和探测路径加载它。如果这些与子AppDomain
不同,则程序集将不会被解析,并且将抛出(其他)异常。
答案 1 :(得分:1)
这种情况可能有多种原因。 http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx上的事件文档详细介绍了这种复杂性如果没有什么似乎适用,请您发布repro代码吗?
答案 2 :(得分:0)
我的猜测是在处理异常时不调用处理程序。即通过上面的try {} catch {}。
答案 3 :(得分:0)
我没有真正理解为什么不调用处理程序。
我最终在加载程序集的Main方法中使用FirstChanceException而不是UnhandledException。像这样:
AppDomain.CurrentDomain.FirstChanceException +=
(obj, e) => Loger.WriteError(
e.Exception.ToString(),
e.Exception.Message,
"default solution"
);
答案 4 :(得分:0)
这是一个迟到的回复,但是如果你问我(VS2012 / .NET 4.5)似乎工作正常,在调用ExecuteAssembly之前需要注册异常处理程序:(我有一个导致Access的子进程通过写入空引用(不安全代码)来强制崩溃并且它触发下面的HandleException:
public static void HandleException(object a_s, UnhandledExceptionEventArgs a_args)
{
var _e = (Exception)a_args.ExceptionObject;
Console.WriteLine(_e.GetType().ToString(), _e.Message, "default solution");
}
public void StarProcessWithinAppDomain(string fileName)
{
try
{
// New appdoamin / check exception isolation level
AppDomain sandBox = AppDomain.CreateDomain("sandBox");
try
{
AppDomain.CurrentDomain.UnhandledException += HandleException;
sandBox.ExecuteAssembly(fileName);
}
catch (Exception ex)
{
Console.WriteLine("An error occurred (inner) within AppDomain, executing \"{0}\":" + "\n" + ex.Message, fileName);
}
finally
{
AppDomain.Unload(sandBox);
}
}
catch (Exception ex)
{
Console.WriteLine("An error occurred within AppDomain, executing \"{0}\":" + "\n" + ex.Message, fileName);
}
}
答案 5 :(得分:0)
FirstChanceException
开火。catch
块。catch
阻止或throw
,则UnhandledException
会触发您的catch
屏蔽确保UnhandledException
无法解雇。