Обработка событий от COM-сервера вне процесса в управляемом приложении STA
По-видимому, управляемые обработчики событий, полученные из неуправляемого внепроцессного COM-сервера, вызываются обратно в поток произвольного пула, а не в основной поток STA (как я и ожидал). Я обнаружил это, отвечая на вопрос оАвтоматизация Internet Explorer, В приведенном ниже кодеDocumentComplete
запускается в потоке без пользовательского интерфейса (так"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");
}
}
}