【发布时间】:2011-12-15 07:42:16
【问题描述】:
我正在尝试编写一个可以加载托管插件的插件系统。如果有任何异常,主机应该能够卸载插件。 对于我的 poc,我在 C# 中有一个示例代码库,它会抛出这样的异常......
public static int StartUp(string arguments)
{
Console.WriteLine("Started exception thrower with args {0}", arguments);
Thread workerThread = new Thread(() =>
{
Console.WriteLine("Starting a thread, doing some important work");
Thread.Sleep(1000);
throw new ApplicationException();
}
);
workerThread.Start();
workerThread.Join();
Console.WriteLine("this should never print");
return 11;
}
然后我有像这样的本机 win32 控制台应用程序..
int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost *pMetaHost = NULL;
HRESULT hr;
ICLRRuntimeInfo *runtimeInfo = NULL;
__try
{
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
hr = pMetaHost->GetRuntime(L"v4.0.30319",IID_ICLRRuntimeInfo,(LPVOID*)&runtimeInfo);
ICLRRuntimeHost *runtimeHost = NULL;
hr = runtimeInfo->GetInterface(CLSID_CLRRuntimeHost,IID_ICLRRuntimeHost, (LPVOID*)&runtimeHost);
ICLRControl* clrControl = NULL;
hr = runtimeHost->GetCLRControl(&clrControl);
ICLRPolicyManager *clrPolicyManager = NULL;
clrControl->GetCLRManager(IID_ICLRPolicyManager, (LPVOID*)&clrPolicyManager);
clrPolicyManager->SetDefaultAction(OPR_ThreadAbort,eUnloadAppDomain);
hr = runtimeHost->Start();
DWORD returnVal = NULL;
hr = runtimeHost->ExecuteInDefaultAppDomain(L"ExceptionThrower.dll",L"ExceptionThrower.MainExceptionThrower",L"StartUp",L"test",&returnVal);
runtimeHost->Release();
}
__except(1)
{
wprintf(L"\n Error thrown %d",e);
}
return 0;
}
问题是如果我使用上面的代码,主机将完成运行托管代码(“这不应该打印”行最终会打印) 如果我删除 clrPolicyManager->SetUnhandledExceptionPolicy(eHostDeterminedPolicy),那么主机进程会崩溃。
可以在非托管主机中进行任何操作以从运行时优雅地删除错误的应用程序并继续工作吗?
【问题讨论】:
-
您的代码启用了 .NET 1.x 异常处理策略。这只是终止线程。不是您想要的,您还需要调用 ICLRPolicyManager::SetDefaultAction() 来告诉它在线程中止时卸载应用程序域。你在某个地方还有一个死线程,使用 __try/__catch 来捕获异常。
-
我添加了以下行 clrPolicyManager->SetDefaultAction(OPR_ThreadAbort,eUnloadAppDomain);到代码,我更新了代码,但效果一样,宿主进程还是崩溃
-
您可能错过了评论中的“死线”部分。您必须捕获 SEH 异常。异常代码为 0xe0434f4d。 msdn.microsoft.com/en-us/library/s58ftw19%28v=VS.100%29.aspx
标签: c# clr clr-hosting