为什么这个NServiceBus消息处理程序在调用Task.CompletedTask时抛出System.MethodAccessException?

时间:2017-01-18 16:09:59

标签: azure nservicebus

在查看文档并尝试查找开发人员遇到此错误的其他示例后,我有点卡住了。我们正在使用NServiceBus 6,偶尔会在调用System.MethodAccessException时在我们的消息处理程序中获得return Task.CompletedTask。它似乎只在处理程序部署在Azure辅助角色中时发生(而不是在模拟器中运行)。我们正在使用Azure Service Bus传输。

  public Task Handle(UpdatePatientAccommodationCode message, IMessageHandlerContext context)
    {
        Console.WriteLine($"Handling [{message.GetType()}]");
        var patientVisit = LoadByExternalPatientId(message.ClientId, message.ExternalPatientId);

        var mappedEvent = patientVisit.HandleCommand(message);

        if (patientVisit.IsEventAdded)
            PatientVisitEventStore.Save(patientVisit);

        return mappedEvent == null ? Task.CompletedTask : context.Publish(mappedEvent);
    }

实际的异常如下所示:

System.MethodAccessException: Attempt by method 'XXX.Handlers.PatientVisitHandler.Handle(XXX.UpdatePatientAccommodationCode, NServiceBus.IMessageHandlerContext)' to access method 'System.Threading.Tasks.Task.get_CompletedTask()' failed.
at XXX.Handlers.PatientVisitHandler.Handle(UpdatePatientAccomm     odationCode message, IMessageHandlerContext context) in PatientVisitHandler.cs:  line 314
at NServiceBus.InvokeHandlerTerminator.Terminate(IInvokeHandlerContext context)       in   C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Pipeline\Incoming\Invok  eHandlerTerminator.cs: line 24
at NServiceBus.LoadHandlersConnector.<Invoke>d__1.MoveNext() in     C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Pipeline\Incoming\LoadH   andlersConnector.cs: line 40

2 个答案:

答案 0 :(得分:6)

我怀疑你的代码在本地有.NET framework 4.6.x,它支持Task.CompletedTask。部署到CS并使用低于版本5的OS family时,将不支持4.6.x您将需要使用启动任务来安装4.6.x或迁移到OS Family 5(Server 2016) )。

答案 1 :(得分:3)

这很奇怪。从Task.CompletedTask的参考来源来看,我无法想出这可能发生的情况。静态缓存的任务使用RAN_TO_COMPLETIONDO_NOT_DISPOSE进行初始化。基于此,我建议您确定是否使用.NET Framework 4.6或更高版本。如果您这样做,但仍然看到异常,请尝试将Task.CompletedTask替换为

static class TaskEx
{
   public static readonly Task CompletedTask = Task.FromResult(0); 
}