【发布时间】:2010-02-19 00:27:59
【问题描述】:
首先,对篇幅表示歉意……
我有一个类似于 MAF 的主机/插件应用程序。我们没有使用任何 System.Addin 或关联的命名空间,因为这是一个自定义插件架构,其中包含多个 AppDomain。 Host UI(用户界面)在它自己的应用程序循环(AppDomain)中运行。当双击列表视图中的项目时,会发生以下情况:
private static void StartPeripheralModule(string modName)
{
AppDomain domain = AppDomain.CreateDomain(modName);
// add to appdomains collection
HostDomains[modName] = domain;
// instances the module for access to the module's Start() method
IModule module = (IModule)domain.CreateInstanceAndUnwrap(
ModuleManager.Modules[modName].Name,
ModuleManager.Modules[modName].EntryPoint.FullName);
// instance the adapter (inherits MBR)
module.Adapter = new ModuleAdapter(modName, module); // also saves a ref. to the IModule object
// publish events decorated with [Serializable]
module.Adapter.ModuleStarted += new ModuleAdapter.ModuleStartEventHandler(Adapter_ModuleStarted);
module.Adapter.ModuleStopped += new ModuleAdapter.ModuleStopEventHandler(Adapter_ModuleStopped);
module.Adapter.ModuleFaulted += new ModuleAdapter.ModuleFaultEventHandler(Adapter_ModuleFaulted);
// add to adapters collection
HostAdapters[modName] = module.Adapter;
// asynchronous startup
Action startup = module.Start;
startup.BeginInvoke(null , null);
}
在module.Start():
[STAThread]
public void Start( )
{
// do Start
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MdiForm = new UnitMDIForm();
MdiForm.FormClosed += new FormClosedEventHandler(MdiForm_FormClosed);
adapter.OnModuleStarted(new ModuleAdapter.ModuleStartEventArgs(adapter));
Application.Run(MdiForm);
}
MdiForm_FormClosed 只是通过插件的 UI 告诉主机模块插件正在关闭,并开始在 AppDomain 上关闭程序。模块插件按预期启动,事件OnModuleStarted 工作正常。当再次双击列表视图项时,模块应该关闭:
public static void UnloadInstance(string modName)
{
Action shutdown = HostAdapters[modName].Module.Shutdown;
IAsyncResult iaRes = shutdown.BeginInvoke(null , null);
while (!iaRes.IsCompleted) // poll wait state
{
Thread.Sleep(250);
hostListener.Write(".");
}
}
模块插件中的关机功能:
public void Shutdown( )
{
if (MdiForm.InvokeRequired)
{
MdiForm.Invoke((MethodInvoker)delegate
{
MdiForm.FormClosed -= MdiForm_FormClosed;
Application.Exit();
});
}
else
{
MdiForm.FormClosed -= MdiForm_FormClosed;
Application.Exit();
}
adapter.OnModuleStopped(new ModuleAdapter.ModuleStopEventArgs(adapter));
}
取消订阅 MdiForm.FormClosed 事件的原因是为了防止双重触发。只要Application.Exit() 我得到 1 - 2 '.' (点)来自轮询机制,然后:
在 mscorlib.dll 中发生了“System.Threading.ThreadAbortException”类型的第一次机会异常 UnitTestWinForm.dll 中发生了“System.Threading.ThreadAbortException”类型的第一次机会异常 UnitTestWinForm.dll 中出现“System.Threading.ThreadAbortException”类型的异常,但未在用户代码中处理
不用说,我们从来没有达到我们的OnModuleStopped 事件,我们正式卸载 AppDomain 并从我们的集合中删除它和适配器。我现在放了一个 try/catch 块,看看我是否能从错误中得到更多。据我了解,我在退出应用程序消息循环然后卸载域时遵循正确的程序。这使模块能够清理其资源等。
谁能告诉我我做错了什么和/或我应该怎么做?
【问题讨论】:
标签: c# .net-3.5 asynchronous appdomain