Warum ist das COM-Interop-Ereignis nicht während des Betriebes unter einem STA-Thread angehoben?
-
06-07-2019 - |
Frage
Kann jemand bitte erklären, warum das Ereignis „OnNewMail“ nicht ausgelöst wird, wenn in dem folgenden Code einen STA-Thread mit? Das Programm versucht, die Rückzahlungs Bibliothek zu verwenden eingehende Outlook Mails abzufangen.
class Program
{
[STAThread()] // When this line is deleted the application works
static void Main(string[] args)
{
RDOSession session = GetSession();
session.OnNewMail += Session_OnNewMail;
Console.ReadLine();
}
static void Session_OnNewMail(string EntryID)
{
Console.WriteLine("New mail received");
}
private static RDOSession GetSession()
{
var session = new RDOSession();
var application = new ApplicationClass();
session.MAPIOBJECT = application.Session.MAPIOBJECT;
return session;
}
}
Lösung
COM auf einem STAThread ausgeführt wird, verwendet eine Meldungsverteilschleife Ereignisse und Methoden aufrufen zu erhöhen. Wenn in einer Konsolenanwendung gibt es kein Fenster ist für Sie Nachrichten zu pumpen, so müssen Sie die Pumpe selbst laufen. (Mehrere der .NET-Synchronisationsverfahren wird dies für Sie tun - einen Blick auf WaitOne etc ...)
Wenn das Objekt innerhalb eines Standard-MTA-Thread glücklich ist -. Sie können besser dran mit, dass, wenn Sie benötigen diese von einer Konsolenanwendung tun
Statt Readline - Sie können für einen Schlüssel abzufragen und Pumpe-Nachrichten mit dieser:
while (Console.Read() == 0)
{
Thread.CurrentThread.Join(100);
}
... aber das ist ein Hack.
Mischen COM, Konsolenanwendungen und [STAThread] ist ein bisschen faul und zu anderen Problemen führen kann: http://support.microsoft.com/default.aspx/kb/828988
Andere Tipps
Wenn die Lauffläche STA-Thread ist und Sie zur Eingabe warten die Bibliothek nicht alles zur gleichen Zeit tun kann, und hat keine Chance, das Ereignis ausgelöst, wenn eine E-Mail ankommt.
Das Problem hat mit ziemlicher Sicherheit mit Nachrichtenpump zu tun.
Wenn wir nicht wissen, welche Art von COM-Objekt RDOSession ist (STA, MTA, etc ...) können wir nur als spekulieren, was tatsächlich geht.
Meine Vermutung ist, dass RDOSession ein MTA COM-Objekt ist und dass irgendwie hat der Ereigniscode um das Ereignis zu einem STA-Proxy oder ein Objekt gebunden ist. Dies bedeutet, dass ein Teil der Erhöhung des OnNewMail Ereignis die Erhöhung auf den STA-Thread Marschall muss. Dies beinhaltet Fenster Message Passing. Sie sind ein einfachen Readline Anruf zu tun, die ein blockierenden Anruf und wird nicht Nachrichten verarbeiten. Daher werden Sie nicht immer die Veranstaltung.