3

NServiceBus v3.3.0.0 を見ています。MessageHandler で外部 WCF サービスを呼び出します。

WCF サービスが同期的に呼び出され、そのサービスが例外をスローした場合、NServiceBus はそれを完全に処理し、構成に従ってプロセスを再試行します。

ただし、WCF サービスが非同期で呼び出され、例外がスローされると、サブスクライバー プロセスがクラッシュします。

したがって、たとえば、これは service.Update がスローされた場合に例外をうまく処理します

   public class LeagueMessageHandler : IHandleMessages<LeagueMessage>
   {
       public void Handle(LeagueMessage message)
       {
           var service = new LeagueService.LeagueContractClient();
           var league = service.Update(leagueDto);
       }
   }

ただし、service.UpdateAsync の呼び出しで例外がスローされると、プロセスがクラッシュします。

   public class LeagueMessageHandler : IHandleMessages<LeagueMessage>
   {
       public async void Handle(LeagueMessage message)
       {
           var service = new LeagueService.LeagueContractClient();
           var league = await service.UpdateAsync(leagueDto);
       }
   }

WCF サービスは、サービス参照としてクラス ライブラリに追加されただけで、Async メソッド ラッパーを生成します。

Adam と Udi のコメントの後で編集します。

この問題は NServiceBus とは無関係のようで、コンソール アプリケーションが例外をスローする非同期メソッドを処理する方法に関係しているようです。スレッドを参照してください

非同期から未処理の例外をキャッチする

スティーブン・クリアリーがこれを書いた

http://nuget.org/packages/Nito.AsyncEx

これは、例外のキャッチを処理する独自の SynchronisationContext をロールするのに役立ちます。したがって、上記のWCF呼び出しは次のようにラップされます...

        var league = AsyncContext.Run(() => service.UpdateAsync(leagueDto));

例外がスローされると、そのコンテキスト内でキャッチされ、コンソール アプリが閉じなくなります。

4

1 に答える 1

3

非同期と呼ぶと、メッセージを処理しているスレッドとは別のスレッドで例外が発生します。そのため、どのメッセージがその例外を引き起こしたのかを NServiceBus が知る方法がないため、何もロールバックできません。

NServiceBus を使用する場合、アーキテクチャ全体はすでに非同期になっています。実際には、これらの WCF 呼び出しを非同期で実行する必要はありません。

于 2012-11-28T08:07:31.737 に答える