このCOM相互運用イベントがSTAスレッドの下で実行中に発生しないのはなぜですか?

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

  •  06-07-2019
  •  | 
  •  

質問

イベント" OnNewMail"の理由を誰か説明してください。以下のコードでSTAスレッドを使用すると発生しませんか?プログラムは、受信ライブラリを使用して受信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;
    }
}
役に立ちましたか?

解決

STAThreadで実行されている

COMは、メッセージポンプを使用してイベントを発生させ、メソッドを呼び出します。コンソールアプリケーションでは、メッセージを送信するためのウィンドウがないため、自分でポンプを実行する必要があります。 (いくつかの.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はMTA COMオブジェクトであり、イベントコードが何らかの形でイベントをSTAプロキシまたはオブジェクトにバインドしていると思います。これは、OnNewMailイベントの発生の一部が、発生をSTAスレッドにマーシャリングする必要があることを意味します。これには、ウィンドウメッセージの受け渡しが含まれます。ブロッキング呼び出しであり、メッセージを処理しない単純なReadLine呼び出しを行っています。したがって、イベントを取得することはありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top