2012-11-27 52 views
3

我看着NServiceBus v3.3.0.0,在我们的MessageHandler它调用外部WCF服务。NServiceBus的handleMessage异步导致崩溃

如果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服务只是作为服务引用添加到类库中,它会生成异步方法包装器。

在Adam和Udi评论后编辑。

它看起来像问题无关NServiceBus它更与控制台应用程序如何处理异步方法抛出异常的事情。请参阅线程

Catch unhandled exceptions from async

斯蒂芬·克利里写了这

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

它可以帮助你滚你自己SynchronisationContext它处理捕捉异常。所以,上面的WCF调用包装等...

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

当异常被赶它是上下文和控制台应用程序不再关闭内抓获。

+0

在撞车事故发生前您是否遇到过某种错误? –

+0

谢谢Adam。为了完整起见,异常是System.ServiceModel.FaultException:值不能为空。这导致我到其他SO线程关于异步例外的控制台应用程序问题。 – applefish

回答

3

当你调用它异步,异常发生在不同的线程比是处理邮件的一个。出于这个原因,NServiceBus无法知道哪个消息是引发该异常的消息,因此它无法返回任何消息。

使用NServiceBus,你的整体架构已经是异步的 - 实在是没有任何需要执行这些WCF异步调用。

+0

我认为这个问题与NServiceBus无关,它与控制台应用程序如何处理异步调用引发异常有关。 – applefish

+0

感谢您的回复Udi。如果对WCF服务的调用是同步的,那么阻塞该线程?我很谨慎,因为我知道特定服务的响应速度有时会很慢。 – applefish

+0

如果WCF调用是同步的,是的,它会阻塞该线程,但这就是为什么你有一个多线程进程。 –