Warum ist das COM-Interop-Ereignis nicht während des Betriebes unter einem STA-Thread angehoben?

StackOverflow https://stackoverflow.com/questions/1017968

  •  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;
    }
}
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top