首先,道歉......
我有一个类似于MAF的主机/插件应用程序。我们没有使用任何System.Addin或相关的命名空间,因为这是一个具有多个AppDomain的自定义插件架构。主机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
正常工作。再次双击listview项时,模块应该关闭:
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”类型的异常,但未在用户代码中处理
毋庸置疑,我们从未到达我们正式卸载AppDomain的OnModuleStopped
事件,并从我们的集合中删除它和适配器。我现在正在尝试使用try / catch块来查看是否可以从错误中获得更多信息。据我所知,我正在遵循退出应用程序消息循环然后卸载域的正确过程。这使模块能够清理它的资源等。
任何人都可以告诉我我做错了什么和/或我应该如何做到这一点?
答案 0 :(得分:1)
这可能会有所帮助......
在您的应用中,订阅:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
Application.ThreadException += ApplicationThreadException;
(参见帮助,他们可能会让事情变得更容易,但有时候在调试模式下你会想要这样做)
我认为你不应该从模块调用Application.Exit(),它会(据我所知)关闭整个应用程序。
或许看看像NUnit这样的工具如何加载和卸载AppDomains - 我从来没有试过卸载过一个....
PK: - )