停止Application环中学的AppDomain [英] Stopping Application Loop in secondary AppDomain

查看:215
本文介绍了停止Application环中学的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 。该模块插件正常启动和事件 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆