どうやら、管理されていないアウトプロセス COM サーバーから供給されたイベントの管理されたハンドラーは、メインの STA スレッドではなく、ランダム プール スレッドでコールバックされるようです (予想どおり)。Internet Explorer の自動化に関する質問に回答しているときに、これを発見しました。以下のコードでDocumentComplete
は、非 UI スレッドで起動されます (したがって、デバッグ出力とは異なります) "Event thread"
。"Main thread"
したがって、this.Invoke
メッセージボックスを表示するために使用する必要があります。私の知る限り、この動作は、STA スレッドからサブスクライブされたイベントが自動的に同じスレッドにマーシャリングされるアンマネージ COM クライアントとは異なります。
従来の 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");
}
}
}