Behandeln von Ereignissen von einem COM-Server außerhalb des Prozesses in einer verwalteten STA-Anwendung
Anscheinend werden verwaltete Handler für Ereignisse, die von einem nicht verwalteten Out-of-Process-COM-Server stammen, in einem zufälligen Pool-Thread anstelle des STA-Hauptthreads (wie erwartet) zurückgerufen. Ich habe dies bei der Beantwortung einer Frage am entdecktInternet Explorer-Automatisierung. Im Code unten,DocumentComplete
wird auf einem Nicht-UI-Thread ausgelöst (so"Event thread"
ist nicht dasselbe wie"Main thread"
in der Debug-Ausgabe). Also muss ich verwendenthis.Invoke
um ein Meldungsfeld anzuzeigen. Meines Wissens unterscheidet sich dieses Verhalten von nicht verwalteten COM-Clients, bei denen Ereignisse, die von einem STA-Thread abonniert wurden, automatisch auf denselben Thread zurückgeführt werden.
Was ist der Grund für eine solche Abkehr vom traditionellen COM-Verhalten? Bisher habe ich keine Referenzen gefunden, die dies bestätigen.
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");
}
}
}