.NET 异步核心中的 Rebus 崩溃
Rebus crash in .NET async core
我正在尝试将现有网站从 Rebus 0.45 升级到 Rebus 2.0,但 运行 遇到 System.Web.ThreadContext.AssociateWithCurrentThread 因空引用而崩溃的问题。我完全不知道为什么,所以我正在寻找我可以寻找的可能原因。
我唯一的踪迹是 Windows 事件日志,它在尝试发送消息时记录了以下内容:
An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/1/ROOT/website
Process ID: 14460
Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
StackTrace: at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.<>c.<ThrowAsyncIfNecessary>b__18_0(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
该网站是 运行ning ASP.NET MVC 3.0,带有 Castle Windsor 依赖项注入器,并使用 Rebus.SqlServer 作为单向客户端进行传输设置:
var busConfigurer = Configure.With(new CastleWindsorContainerAdapter(container))
.Logging(l => l.Use(new RebusLoggerFactory()))
.Routing(t => t.TypeBased().AddEndpointMappingsFromAppConfig())
.Subscriptions(s => s.StoreInSqlServer(dbConnectionString, "RebusSubscriptions_v2"))
.Transport(t => t.UseSqlServerAsOneWayClient(dbConnectionString, "RebusMessages_v2"))
Start();
IIS 是为“.NET 4.5”应用程序池设置的。
网站启动,总线日志:
- Supplied connection string will be modified to enable MARS
- Database already contains a table named 'RebusMessages_v2' - will not create anything
- Supplied connection string will be modified to enable MARS
- Starting periodic task 'CleanupTrackedErrors' with interval 00:01:00
- Starting bus 1
- Started
稍后通过 Rebus 发送一条消息,记录:
- Sending SubmissionCreatedEvent -> SelfService.Service.input
... 繁荣!整个应用程序崩溃。
在发送消息之前,应用程序已与 NHibernate 交互以存储有关操作的详细信息。
更新
通过将 Bus.Send(msg)
更改为 Bus.Send(msg).Start()
我可以同步触发相同的错误并在 Visual Studio 中调试时获得以下堆栈跟踪:
Exception thrown: 'System.NullReferenceException' in System.Web.dll
Exception thrown: 'System.NullReferenceException' in mscorlib.dll
System.Transactions Critical: 0 :
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>/LM/W3SVC/1/ROOT/website-2-131225642632547395</AppDomain>
<Exception><ExceptionType>System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Object reference not set to an instance of an object.</Message><StackTrace> at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task&amp; currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.&lt;&gt;c.&lt;ThrowAsyncIfNecessary&gt;b__18_0(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</StackTrace><ExceptionString>System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task&amp; currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.&lt;&gt;c.&lt;ThrowAsyncIfNecessary&gt;b__18_0(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</ExceptionString></Exception></TraceRecord>
更新二
用 bus.Advanced.Routing.Send("SelfService.Service.input", msg)
替换 Bus.Publish(msg)
有效。所以显然 subscription/routing 的东西有问题,因为 Send(...)
绕过了那个。
更新三
显然在 web.config 中添加 <httpRuntime targetFramework="4.6" ...
解决了问题(到目前为止,它似乎仍然有点不稳定)。 web.config 已经有 <compilation ... targetFramework="4.6">
:
<system.web>
<httpRuntime targetFramework="4.6" maxRequestLength="5000" requestValidationMode="2.0" />
<compilation debug="true" targetFramework="4.6">
<assemblies>...</assemblies>
</compilation>
<pages validateRequest="false">
<namespaces>...</namespaces>
</pages>
</system.web>
修复结果是为了确保网站是 运行 .NET 4.5 或更高版本:
<system.web>
<httpRuntime targetFramework="4.6" />
<compilation targetFramework="4.6">
...
</compilation>
</system.web>
显然,ASP.NET 团队在 .NET 4.5 中 ASP.NET 提高了任务意识。
我正在尝试将现有网站从 Rebus 0.45 升级到 Rebus 2.0,但 运行 遇到 System.Web.ThreadContext.AssociateWithCurrentThread 因空引用而崩溃的问题。我完全不知道为什么,所以我正在寻找我可以寻找的可能原因。
我唯一的踪迹是 Windows 事件日志,它在尝试发送消息时记录了以下内容:
An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/1/ROOT/website
Process ID: 14460
Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
StackTrace: at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.<>c.<ThrowAsyncIfNecessary>b__18_0(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
该网站是 运行ning ASP.NET MVC 3.0,带有 Castle Windsor 依赖项注入器,并使用 Rebus.SqlServer 作为单向客户端进行传输设置:
var busConfigurer = Configure.With(new CastleWindsorContainerAdapter(container))
.Logging(l => l.Use(new RebusLoggerFactory()))
.Routing(t => t.TypeBased().AddEndpointMappingsFromAppConfig())
.Subscriptions(s => s.StoreInSqlServer(dbConnectionString, "RebusSubscriptions_v2"))
.Transport(t => t.UseSqlServerAsOneWayClient(dbConnectionString, "RebusMessages_v2"))
Start();
IIS 是为“.NET 4.5”应用程序池设置的。
网站启动,总线日志:
- Supplied connection string will be modified to enable MARS
- Database already contains a table named 'RebusMessages_v2' - will not create anything
- Supplied connection string will be modified to enable MARS
- Starting periodic task 'CleanupTrackedErrors' with interval 00:01:00
- Starting bus 1
- Started
稍后通过 Rebus 发送一条消息,记录:
- Sending SubmissionCreatedEvent -> SelfService.Service.input
... 繁荣!整个应用程序崩溃。
在发送消息之前,应用程序已与 NHibernate 交互以存储有关操作的详细信息。
更新
通过将 Bus.Send(msg)
更改为 Bus.Send(msg).Start()
我可以同步触发相同的错误并在 Visual Studio 中调试时获得以下堆栈跟踪:
Exception thrown: 'System.NullReferenceException' in System.Web.dll
Exception thrown: 'System.NullReferenceException' in mscorlib.dll
System.Transactions Critical: 0 :
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>/LM/W3SVC/1/ROOT/website-2-131225642632547395</AppDomain>
<Exception><ExceptionType>System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Object reference not set to an instance of an object.</Message><StackTrace> at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task&amp; currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.&lt;&gt;c.&lt;ThrowAsyncIfNecessary&gt;b__18_0(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</StackTrace><ExceptionString>System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task&amp; currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.&lt;&gt;c.&lt;ThrowAsyncIfNecessary&gt;b__18_0(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</ExceptionString></Exception></TraceRecord>
更新二
用 bus.Advanced.Routing.Send("SelfService.Service.input", msg)
替换 Bus.Publish(msg)
有效。所以显然 subscription/routing 的东西有问题,因为 Send(...)
绕过了那个。
更新三
显然在 web.config 中添加 <httpRuntime targetFramework="4.6" ...
解决了问题(到目前为止,它似乎仍然有点不稳定)。 web.config 已经有 <compilation ... targetFramework="4.6">
:
<system.web>
<httpRuntime targetFramework="4.6" maxRequestLength="5000" requestValidationMode="2.0" />
<compilation debug="true" targetFramework="4.6">
<assemblies>...</assemblies>
</compilation>
<pages validateRequest="false">
<namespaces>...</namespaces>
</pages>
</system.web>
修复结果是为了确保网站是 运行 .NET 4.5 或更高版本:
<system.web>
<httpRuntime targetFramework="4.6" />
<compilation targetFramework="4.6">
...
</compilation>
</system.web>
显然,ASP.NET 团队在 .NET 4.5 中 ASP.NET 提高了任务意识。