从处理外的进程内COM服务器事件管理STA应用从处理外的进程内COM服务器事件管理STA应用(Han

2019-05-12 08:18发布

显然,管理事件,从非托管了进程外COM服务器采购的处理,被称为回随机池中的线程,而不是主STA线程上(如我期望)。 我在回答上一个问题发现了这个Internet Explorer的自动化 。 在下面的代码, DocumentComplete是在非UI线程烧制(因此"Event thread"是不一样的"Main thread"在调试输出)。 因此,我必须使用this.Invoke显示一个消息框。 据我所知,这种行为是从非托管COM客户端,在事件从一个STA线程订阅不同的自动编组回同一个线程。

什么是从传统的COM等行为偏离背后的原因是什么? 到目前为止,我还没有发现任何引用确认这一点。

using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace WinformsIE
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs ev)
        {
            var ie = (SHDocVw.InternetExplorer)Activator.CreateInstance(Type.GetTypeFromProgID("InternetExplorer.Application"));
            ie.Visible = true;
            Debug.Print("Main thread: {0}", Thread.CurrentThread.ManagedThreadId);
            ie.DocumentComplete += (object browser, ref object URL) =>
            {
                string url = URL.ToString();
                Debug.Print("Event thread: {0}", Thread.CurrentThread.ManagedThreadId);
                this.Invoke(new Action(() =>
                {
                    Debug.Print("Action thread: {0}", Thread.CurrentThread.ManagedThreadId);
                    var message = String.Format("Page loaded: {0}", url);
                    MessageBox.Show(message);
                }));
            };
            ie.Navigate("http://www.example.com");
        }
    }
}

Answer 1:

我发现下面的摘录从亚当森的“.NET和COM:完全的互操作性指南” :

如果COM对象生活在一个STA,从MTA线程任何电话都这么COM对象保持其世界线程关联的适当编组。 但是,在另一个方向上,则不会发生这样的线程或上下文切换。

因此,这是预期的行为。 到目前为止,关于这个问题我唯一能找到的(半官方)源。



文章来源: Handling events from out-of-proc COM server in managed STA application