views:

295

answers:

3

Can somebody please explain why the event "OnNewMail" is not raised when using an STA thread in the code below? The program attempts to use the Redemption library to intercept incoming outlook mails.

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

When the tread is STA thread and you wait for input the library can't do anything at the same time and has no chance to fire the event when an email arrives.

sharptooth
A: 

The problem almost certainly has to do with message pumping.

Unless we know what type of COM object RDOSession is (STA, MTA, etc ...) we can only speculate as to what is actually going on.

My guess is that RDOSession is an MTA COM object and that somehow the event code has bound the event to an STA proxy or object. This means that part of the raising of the OnNewMail event must marshal the raise onto the STA thread. This involves window message passing. You are doing a simple ReadLine call which is a blocking call and will not process messages. Hence you won't ever get the event.

JaredPar
+1  A: 

COM running on an STAThread uses a message pump to raise events and call methods. When in a console application there isn't a window to pump messages for you so you need to run the pump yourself. (Several of the .NET synchronisation methods will do this for you - have a look at WaitOne etc...)

If the object is happy within a default MTA thread - you may be better off using that if you need to do this from a console application.

Instead of ReadLine - you can poll for a key and pump messages using this:

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

...but this is a hack.

Mixing COM, console apps and [STAThread] is a bit fishy and can result in other problems: http://support.microsoft.com/default.aspx/kb/828988

Chip Phat