非序列未处理的异常,我们正在使用System.AddIn到插件加载到单独的AppDomain的孩子打交道,我们卸载加载的AppDomain中,如果有未处理的异常。从一个孩子的AppDomain
由于版本2.0的.NET的默认行为是拆除整个过程,如果有任何AppDomain有未处理的异常,我们通过使用我们的App.config中的“legacyUnhandledExceptionPolicy”选项,然后手动拆除如果未处理的异常处于主AppDomain中,则进行处理;如果处于加载项中,则卸载相应的AppDomain。
除了一个小问题外,这一切都很好:未处理的异常总是从子AppDomain冒泡到主要的,并且如果它们不是可序列化的,则它们无法成功跨过AppDomain边界。
相反,我们得到一个SerializationException出现在主AppDomain中的UnhandledException,导致我们的应用程序本身推倒。
我能想到这个问题的一些可能的解决方案:
我们不能推倒未处理SerializationExceptions(呸)的过程。
我们可以从孩子的AppDomain传播到主要的AppDomain停止例外。
我们可以更换序列化的,也许使用序列代理人和系列化粘合剂的不可序列化的例外。 [编辑:看到最后为什么这是不可能的使用代理人]
然而,第一个是很可怕的,我已经搞清楚怎么做任何其他选项有交叉不成功AppDomain远程处理。
任何人都可以提供一些建议?任何帮助表示赞赏。
要重现创建具有以下的App.config控制台应用程序:
<?xml version="1.0"?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true"/>
</runtime>
</configuration>
和以下的代码:
class Program
{
private class NonSerializableException : Exception
{
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += MainDomain_UnhandledException;
AppDomain childAppDomain = AppDomain.CreateDomain("Child");
childAppDomain.UnhandledException += ChildAppDomain_UnhandledException;
childAppDomain.DoCallBack(
() => new Thread(delegate() { throw new NonSerializableException(); }).Start());
Console.ReadLine();
}
static void MainDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("Main AppDomain Unhandled Exception: " + e.ExceptionObject);
Console.WriteLine();
}
static void ChildAppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("Child AppDomain Unhandled Exception: " + e.ExceptionObject);
Console.WriteLine();
}
}
编辑:我使用反射器以查看是否有任何方法可以访问跨AppDomain中使用的BinaryFormatter远程处理,但它在CrossAppDomainSerializer类中的代码结束:
internal static void SerializeObject(object obj, MemoryStream stm)
{
BinaryFormatter formatter = new BinaryFormatter();
RemotingSurrogateSelector selector = new RemotingSurrogateSelector();
formatter.SurrogateSelector = selector;
formatter.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
formatter.Serialize(stm, obj, null, false);
}
因此,该方法在本地创建的格式,并明确是没有办法自己带上代孕...我认为这使得任何朝这个方向作更多的努力是徒劳的。
嗨詹姆斯,你有没有找到一个解决这个? – Joshjje 2013-11-22 20:06:22
@Joshjje,不是一个好的解决方案......我们最终只是处理每个AppDomain中的未处理的异常,然后让AppDomain从那里卸载它自己。这显然需要信任每个加载项来设置此系统,谢天谢地,我们可以为我们的应用程序。虽然我没有找到一种方法来管理主AppDomain内的整个流程。 – 2013-12-23 14:16:40