none
BackgroundWorkerのバックグラウンド処理で例外「RPC_E_CALL_REJECTED」をフィルタできない RRS feed

  • 質問

  • お世話になります。

    C#でCOMを使用して外部プロセスを操作する
    WindowsFormアプリケーションを作成しています。

    その外部プロセスがビジー状態にある場合に備え、
    下記を参考にメッセージフィルタでのリトライ処理を実装しました。
    http://msdn.microsoft.com/ja-jp/library/ms228772(v=vs.80).aspx

    実装したメッセージフィルタについて、メインスレッドでの
    外部プロセス操作でRPC_E_CALL_REJECTEDが返された場合は
    フィルタが動作し、リトライされることを確認しました。

    ところが、System.ComponentModel.BackgroundWorkerの
    DoWorkイベント内で外部プロセスを操作し、RPC_E_CALL_REJECTEDが
    返された場合はフィルタが動作せず、ComException(RPC_E_CALL_REJECTED)が
    スローされてしまいます。

    また、DoWork内でメッセージフィルタを登録(CoRegisterMessageFilter呼び出し)
    してみましたが、フィルタは動作しませんでした。

    メインスレッド以外でメッセージフィルタを動作させたいのですが、
    何か解決策は無いでしょうか。

    よろしくお願い致します。

    ------------------------
    環境
    VisualStudio 2005
    Windows 7 (x86)
    2011年4月13日 7:18

回答

  • CoRegisterMessageFilter Function (COM)

    の記述によると、

    Only one message filter can be registered for each thread. Threads in multi-threaded apartments cannot have message filters.

    だそうです。BackgroundWorker で使用されるスレッドは確かスレッドプールの物で、スレッドプールが使用するスレッドはすべて MTA(Multi Thread Apartment)として初期化されるので、BackgroundWorker ではメッセージフィルタを使えないってことになりますね。

    スレッドアパートメントを設定できるのは(そして STA に指定できるのは)、アプリケーションのメインスレッドを除けば直接 System.Threading.Thread クラスを使ってスレッドを実行する場合のみだったはずです(SetApartmentState メソッドで指定)。

    • 回答としてマーク Grape50 2011年4月14日 1:58
    2011年4月13日 7:58
  • STAに加えて、MessageLoopも必要になるので、それも用意してください。

    • 回答としてマーク Grape50 2011年4月14日 1:58
    • 回答としてマークされていない Grape50 2011年4月14日 4:27
    • 回答としてマーク Grape50 2011年4月14日 4:27
    2011年4月13日 9:29

すべての返信

  • CoRegisterMessageFilter Function (COM)

    の記述によると、

    Only one message filter can be registered for each thread. Threads in multi-threaded apartments cannot have message filters.

    だそうです。BackgroundWorker で使用されるスレッドは確かスレッドプールの物で、スレッドプールが使用するスレッドはすべて MTA(Multi Thread Apartment)として初期化されるので、BackgroundWorker ではメッセージフィルタを使えないってことになりますね。

    スレッドアパートメントを設定できるのは(そして STA に指定できるのは)、アプリケーションのメインスレッドを除けば直接 System.Threading.Thread クラスを使ってスレッドを実行する場合のみだったはずです(SetApartmentState メソッドで指定)。

    • 回答としてマーク Grape50 2011年4月14日 1:58
    2011年4月13日 7:58
  • STAに加えて、MessageLoopも必要になるので、それも用意してください。

    • 回答としてマーク Grape50 2011年4月14日 1:58
    • 回答としてマークされていない Grape50 2011年4月14日 4:27
    • 回答としてマーク Grape50 2011年4月14日 4:27
    2011年4月13日 9:29
  • ご教示頂いた方法で試してみます。

    ありがとうございます。

    2011年4月14日 4:31