1

有人可以解释为什么在下面的代码中使用 STA 线程时没有引发事件“OnNewMail”吗?该程序尝试使用 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;
    }
}
4

3 回答 3

1

在 STAThread 上运行的 COM 使用消息泵来引发事件和调用方法。当在控制台应用程序中没有为您泵送消息的窗口时,您需要自己运行泵送。(有几种 .NET 同步方法会为您执行此操作 - 看看 WaitOne 等...)

如果对象在默认 MTA 线程中是满意的 - 如果您需要从控制台应用程序执行此操作,则最好使用它。

而不是 ReadLine - 您可以使用以下方法轮询密钥并抽取消息:

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

...但这是一个黑客。

混合 COM、控制台应用程序和 [STAThread] 有点可疑,可能会导致其他问题:http: //support.microsoft.com/default.aspx/kb/828988

于 2009-06-19T13:55:28.523 回答
0

当线程是 STA 线程并且您等待输入时,库不能同时执行任何操作,并且在电子邮件到达时没有机会触发事件。

于 2009-06-19T13:37:38.623 回答
0

这个问题几乎肯定与消息泵送有关。

除非我们知道 RDOSession 是什么类型的 COM 对象(STA、MTA 等),否则我们只能推测实际发生的情况。

我的猜测是 RDOSession 是一个 MTA COM 对象,并且事件代码以某种方式将事件绑定到 STA 代理或对象。这意味着 OnNewMail 事件引发的一部分必须将引发编组到 STA 线程上。这涉及窗口消息传递。您正在执行一个简单的 ReadLine 调用,这是一个阻塞调用,不会处理消息。因此,您将永远无法获得该事件。

于 2009-06-19T13:40:46.853 回答