停止Application环中学的AppDomain [英] Stopping Application Loop in secondary AppDomain
问题描述
首先,道歉的长度...
First off, apologies for the length...
我有一个主机/插件应用程序类似于MAF。我们不使用任何System.Addin或相关的命名空间,因为这是一个自定义的插件架构,在游戏中多个AppDomain。主机UI(用户接口)上运行在它自己的应用循环(应用程序域)。当在列表视图中的项目是双击会出现以下情况:
I have a Host/Plugin application akin to MAF. We are not using any of the System.Addin or associated namespaces as this is a custom plugin architecture with multiple AppDomains in play. The Host UI (user interface) is running in it's own application loop (AppDomain). When an item in a listview is double-clicked the following occurs:
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
只是告诉主机该模块插件正在通过插件的用户界面关闭,并开始对的AppDomain $ C结束程序$ C>。该模块插件正常启动和事件
OnModuleStarted
工作正常。当ListView项是再次双击该模块应关闭:
MdiForm_FormClosed
simply tells the Host that the module plugin is being closed via the plugin's UI and to begin closing procedures on the AppDomain
. The module plugin starts as expected and the event OnModuleStarted
works fine. When the listview item is once again double-clicked the module should shut down:
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事件取消订阅是prevent二次烧成。只要 Application.Exit()
我得到1 - '。2从轮询机制(点),然后
The reason the MdiForm.FormClosed event is unsubscribed to is to prevent double firing. As soon as the Application.Exit()
I get 1 - 2 '.' (dots) from the polling mechanism and then:
有一个第一次机会异常的类型'System.Threading.ThreadAbortException在mscorlib.dll中发生 第一个机会异常类型的System.Threading.ThreadAbortException在UnitTestWinForm.dll发生 类型'System.Threading.ThreadAbortException的异常UnitTestWinForm.dll发生,但在用户code没有处理
A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll A first chance exception of type 'System.Threading.ThreadAbortException' occurred in UnitTestWinForm.dll An exception of type 'System.Threading.ThreadAbortException' occurred in UnitTestWinForm.dll but was not handled in user code
不用说,我们从来没有达到我们的 OnModuleStopped
事件,我们正式卸载的AppDomain并删除它,从我们收集的适配器。我把现在在一个try / catch块,看看我是否能得到更多的东西,从错误。据我了解,我下面在退出应用程序的消息循环,然后卸载该域的正确步骤。这使模块清理它的资源的能力,等等。
Needless to say, we never reach our OnModuleStopped
event where we officially unload the AppDomain and remove it and the adapter from our collections. I am putting a try/catch block in now to see if I can get anything more from the errors. From what I understand, I am following the proper procedure in exiting the application message loop and then unloading the domain. This gives the module the ability to clean up it's resources, etc.
谁能告诉我我在做什么错误和/或我应该怎么做不同?
推荐答案
这可以帮助...
在你的应用程序,订阅:
In your app, subscribe to:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
Application.ThreadException += ApplicationThreadException;
(见的帮助下,他们可能会让事情变得更容易,但有时在调试模式下,你会希望这个功能)
(see the help, they may make things easier but other times in debug mode you'll want this off)
我不认为你应该从模块调用Application.Exit(),将(据我所知)关闭整个应用程序。
I don't think you should be calling Application.Exit() from the module, it will (as far as I know) shut down the whole app.
也许看怎么像NUnit的负载的工具和卸载应用程序域 - 我从来没有尝试卸载的....
Perhaps look at how A tool like NUnit loads and unloads AppDomains - I have never tried unloading one....
PK: - )
这篇关于停止Application环中学的AppDomain的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!