代码之家  ›  专栏  ›  技术社区  ›  ctacke

消息泵和应用程序域

  •  3
  • ctacke  · 技术社区  · 17 年前

    我有一个C#(FFx 3.5)应用程序,它将DLL作为插件加载。这些插件加载在单独的AppDomain中(出于许多好的原因,这种体系结构无法更改)。这一切都很好。

    我现在需要显示这些插件之一的对话框。记住,我 不能 将对话框表单返回到主应用程序并在那里显示(当前基础结构不支持它)。

    失败1

    失败2

    失败3

    在我的DLL中,我创建了一个表单,名为Application.Run。这肯定会创建一个完整的第二个消息泵。我得到了与故障2相同的行为-对话框行为正常,但调用应用程序没有。

    关于这里到底发生了什么,以及如何从另一个AppDomain的DLL中显示一个对话框,并让调用方和被调用方仍然正确响应和绘制,有什么想法吗?

    3 回复  |  直到 17 年前
        1
  •  4
  •   Jonathan C Dickinson    17 年前

    尝试使用appdomain1的主窗体的BeginInvoke和一个显示来自appdomain2的窗体的委托。所以在伪代码中:

    Appdomain1:
        AppDomain2.DoSomething(myMainForm);
    
    AppDomain2:
        DoSomething(Form parent)
        {
            Form foolishForm = new Form();
            parent.BeginInvoke(new Action( delegate { foolishForm.Show(); } ));
        }
    

    代码可能并不完美,但它展示了这个概念。

    public class Container<T> : MarshalByRefObject
    {
        private T _value;
        public T Value { get { return _value; } set { _value = value; } }
    
        public Container() { }
        public Container(T value) { Value = value; }
    
        public static implicit operator T(Container<T> container)
        {
            return container.Value;
        }
    }
    

    它将包含您向其投掷的对象。

        2
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    12 年前

    application domain ,它是在单独的线程上创建的。我们有一个第三方控件,除非我们调用 System.Windows.Forms.Application.DoEvents() 有规律地

    伪代码:

    <In new thread>
      <Application domain created. Start called inside new application domain.>
      <Start loads new DLL file, calls init function in DLL file>
      <Start loops, calling DoEvents until the DLL file exits>
      <Application domain unloaded>
    <Thread exits>
    

        3
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    12 年前

    我以前使用过的一件事是实现 DomainManager application domain 安全性/绑定/上下文用于处理复杂的或鸡蛋类型的问题,这些问题与将数据泵送到您想要的位置有关;)

    我通常在native.exe中执行此操作,通过COM接口引导CLR(psudo代码,但顺序和方法名称正确;):

    CorBindToRuntimeEx()
    SetHostControl()
    GetCLRControl()
    SetAppDomainManagerType("yourdomainmanger","info")
    // Domain manager set before starting runtime
    Start()
    HostControl -- GetDomainManagerForDefaultDomain()
    DomainManager -- Run()
    

    您的域管理器可以是任何 CLR

    一张便条,如果你在的话 WPF 相同的 UI控件(不需要求助于全新的Window()。