Почему это событие COM-взаимодействия не вызывается при работе в потоке STA?
-
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, который является блокирующим вызовом и не будет обрабатывать сообщения. Следовательно, вы никогда не получите событие. Р>