Pourquoi cet événement d'interopérabilité COM n'est pas déclenché lors de l'exécution sous un thread STA?

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

  •  06-07-2019
  •  | 
  •  

Question

Quelqu'un peut-il expliquer pourquoi l'événement " OnNewMail "? n'est pas déclenché lors de l'utilisation d'un thread STA dans le code ci-dessous? Le programme tente d’utiliser la bibliothèque Redemption pour intercepter les messages Outlook entrants.

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;
    }
}
Était-ce utile?

La solution

COM qui s'exécute sur un chemin STAT utilise une pompe de messages pour déclencher des événements et des méthodes d'appel. Dans une application console, il n'y a pas de fenêtre pour afficher les messages, vous devez donc faire fonctionner la pompe vous-même. (Plusieurs méthodes de synchronisation .NET le feront pour vous - regardez WaitOne etc ...)

Si l'objet est satisfait dans un thread MTA par défaut, mieux vaut l'utiliser si vous avez besoin de le faire à partir d'une application console.

Au lieu de ReadLine - vous pouvez rechercher une clé et pomper des messages en utilisant ceci:

while (Console.Read() == 0)
{
    Thread.CurrentThread.Join(100);
}

... mais c'est un hack.

Le mélange de COM, d’applications console et de [STAThread] est un peu louche et peut entraîner d’autres problèmes: http://support.microsoft.com/default.aspx/kb/828988

Autres conseils

Lorsque la bande de roulement est un thread STA et que vous attendez une entrée, la bibliothèque ne peut rien faire en même temps et n'a aucune chance de déclencher l'événement lorsqu'un courrier électronique arrive.

Le problème est presque certainement lié au pompage de messages.

Si nous ne savons pas quel type d'objet COM est RDOSession (STA, MTA, etc.), nous ne pouvons que spéculer sur ce qui se passe réellement.

Je suppose que RDOSession est un objet COM MTA et que le code de l'événement a lié l'événement à un proxy ou à un objet STA. Cela signifie qu’une partie de la levée de l’événement OnNewMail doit marshaler la relance sur le thread STA. Cela implique un message de fenêtre en passant. Vous effectuez un simple appel ReadLine qui est un appel bloquant et ne traitera pas les messages. Par conséquent, vous n'obtiendrez jamais l'événement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top