MassTransit Consumer中的异常冒泡导致Windows服务崩溃

时间:2014-04-30 08:43:59

标签: .net vb.net multithreading windows-services masstransit

我使用AutoFac为2个消费者设置了一个Windows服务。在一条快乐的道路上,这非常有效。我对MassTransit为我处理异常的行为表示不满。 正如文档所述: http://docs.masstransit-project.com/en/latest/overview/errors.html

  

最简单的方法是让异常泡沫消失   消费者方法和MassTransit将自动捕获异常   为你

当消费者抛出异常时,MassTransit确实会产生错误,但我的服务仍然崩溃:

  

应用程序:WerkgeverService.exe Framework版本:v4.0.30319   描述:由于未处理的异常,进程终止。   异常信息:AutoMapper.AutoMapperMappingException Stack:at   System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__5(System.Object的)   在   System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object的)   在   System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,   System.Threading.ContextCallback,System.Object,Boolean)at   System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,   System.Threading.ContextCallback,System.Object,Boolean)at   System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()   在System.Threading.ThreadPoolWorkQueue.Dispatch()at   System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

记录异常,因为我记录了所有未捕获的异常:

Protected Overrides Sub OnStart(args() As String)
        ' Add code here to start your service. This method should set things
        ' in motion so your service can do its work.
        Try
            Initialize()
            AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf HandleBubbledException
        Catch ex As Exception
            Me.EventLog.WriteEntry(ex.Message, EventLogEntryType.Error)
            Throw
        End Try
    End Sub


    Private Sub HandleBubbledException(sender As Object, args As UnhandledExceptionEventArgs)
        Dim exception = DirectCast(args.ExceptionObject, Exception)
        Me.EventLog.WriteEntry(String.Format("Message: {0} {2}Stacktrace:{2}{1}", exception.Message, exception.StackTrace, Environment.NewLine), EventLogEntryType.Error)
    End Sub

异常本身就是来自AutoMapper的异常,并且确实记录在事件日志中(因此它不由MassTransit处理):

Message: Missing type map configuration or unsupported mapping.

Mapping types:
Int32 -> Int64
System.Int32 -> System.Int64

问题:有什么方法可以防止服务崩溃而不向每个消费者添加try/catch? AFAIK MassTransit应该处理这些......

1 个答案:

答案 0 :(得分:2)

这可能与我的情况有关,但我认为我发现了问题(感谢MassTransit的人)。

问题是我的消费者启动了一个新线程。

Public Sub Consume(message As IConsumeContext(Of IMessage)) Implements Consumes(Of IConsumeContext(Of IMessage)).All.Consume
    HandleMessageAsync(message)
End Sub
Private Async Sub HandleMessageAsync(context As IConsumeContext(Of IMessage))
    Dim something = Await _controller.GetSomething(context.Message)
    Dim response As New MessageResponse
    response.something = something
    context.Respond(response)
End Sub

这个线程不受MassTransit的控制,因此无法从该线程中捕获任何异常。我的解决方案是将其更改为:

Public Sub Consume(context As IConsumeContext(Of IMessage)) Implements Consumes(Of IConsumeContext(Of IMessage)).All.Consume
    Dim something = _controller.GetSomething(context.Message).Result
    Dim response As New MessageResponse
    response.something = something
    context.Respond(response)
End Sub

确保在Consume方法退出之前异常冒泡。否则你必须亲自抓住它。