Почему это событие COM-взаимодействия не вызывается при работе в потоке STA?

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

  •  06-07-2019
  •  | 
  •  

Вопрос

Кто-нибудь может объяснить, почему произошло событие "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;
    }
}
Это было полезно?

Решение

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

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

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

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

... но это взлом.

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top