Почему это событие COM-взаимодействия не вызывается при работе в потоке STA? - PullRequest
1 голос
/ 19 июня 2009

Может кто-нибудь объяснить, почему событие "OnNewMail" не вызывается при использовании потока STA в приведенном ниже коде? Программа пытается использовать библиотеку Redemption для перехвата входящих писем outlook.

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;
    }
}

Ответы [ 3 ]

1 голос
/ 19 июня 2009

COM, работающий на STAThread, использует насос сообщений, чтобы вызывать события и вызывать методы. Когда в консольном приложении нет окна для перекачки сообщений, вам нужно запустить насос самостоятельно. (Несколько методов синхронизации .NET сделают это за вас - взгляните на WaitOne и т. Д.)

Если объект удовлетворен в потоке MTA по умолчанию - вам лучше использовать его, если вам нужно сделать это из консольного приложения.

Вместо ReadLine - вы можете запросить ключ и отправить сообщения, используя это:

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

... но это хак.

Смешивание COM, консольных приложений и [STAThread] немного сложновато и может привести к другим проблемам: http://support.microsoft.com/default.aspx/kb/828988

0 голосов
/ 19 июня 2009

Проблема почти наверняка связана с прокачкой сообщений.

Если мы не знаем, какой тип COM-объекта RDOSession (STA, MTA и т. Д.), Мы можем только догадываться о том, что на самом деле происходит.

Я предполагаю, что RDOSession является COM-объектом MTA и что каким-то образом код события связал событие с прокси или объектом STA. Это означает, что часть инициирования события OnNewMail должна маршалировать повышение в поток STA. Это включает в себя передачу сообщений окна. Вы делаете простой вызов ReadLine, который является блокирующим вызовом и не будет обрабатывать сообщения. Следовательно, вы никогда не получите событие.

0 голосов
/ 19 июня 2009

Когда протектор представляет собой поток STA и вы ожидаете ввода, библиотека не может ничего сделать одновременно и не имеет возможности инициировать событие, когда приходит электронное письмо.

...