NServiceBus HandleMessage异步导致崩溃

时间:2012-11-27 16:29:47

标签: nservicebus

我正在看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无关,它更多地与控制台应用程序如何处理抛出异常的异步方法有关。请看线程

Catch unhandled exceptions from async

Stephen Cleary写了这个

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

它可以帮助您滚动自己的SynchronisationContext来处理捕获异常。所以上面的WCF调用包含了这样......

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

当抛出异常时,它会在该上下文中被捕获,并且控制台应用程序不再关闭。

1 个答案:

答案 0 :(得分:3)

当您将其称为异步时,异常发生在与处理消息的线程不同的线程上。出于这个原因,NServiceBus无法知道哪个消息是导致该异常的消息,因此它无法回滚任何内容。

使用NServiceBus时,您的整体架构已经异步 - 实际上不需要异步执行这些WCF调用。