我正在查看 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 服务只是作为服务引用添加到类库中,它生成异步方法包装器。
在 Adam 和 Udi 评论之后进行编辑。
看起来这个问题与 NServiceBus 无关,它更多地与控制台应用程序如何处理抛出异常的异步方法有关。请看线程
斯蒂芬克利里写了这个
http://nuget.org/packages/Nito.AsyncEx
这可以帮助您滚动自己的 SynchronisationContext 来处理捕获异常。所以上面的 WCF 调用是这样包装的......
var league = AsyncContext.Run(() => service.UpdateAsync(leagueDto));
当抛出异常时,它会在该上下文中被捕获,并且控制台应用程序不再关闭。