未捕获未处理的任务异常
Unhandled task exceptions not being caught
我一直在处理的应用程序最近开始出现间歇性硬崩溃,我无法解释。为了使这更奇怪,我们同时设置了 AppDomain.CurrentDomain.UnhandledException
和 TaskScheduler.UnobservedTaskException
来捕获此类问题。
通常当出现问题时,以上两个都可以正常工作,但在某些情况下它们不会捕获未处理的异常。使事情变得更糟更糟 导致这种情况的异常是 NRE,这意味着我们无法继续追踪正在发生的事情。
我的第一个想法是,我们在未处理的异常处理程序中的代码可能会抛出异常,因此我们在此处加倍处理异常,但到目前为止,这没有任何区别。我们的日志也无法阐明这一点。
这可能是 webapi 的一个错误 and/or 我们用来托管应用程序的 owin 位,我将尝试增加依赖项以查看是否有帮助,但我不认为这会有什么不同。
有没有办法捕获线程池中发生的未处理异常?是否有某种诊断我们可以启用以获取有关发生这种情况的更多信息?
我已无计可施,如有任何帮助,我们将不胜感激。
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Net.HttpListener.EndGetContext(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.Owin.Host.HttpListener.OwinHttpListener.<ProcessRequestsAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__5(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()
在使用任务时我们不执行 async void
,但我们有一种情况 Task.Run
我们不等待或挂起任务。这是:
Task.Run(() => CleanUpAllExpiredErrors());
此方法清除过期的客户端错误(我们捕获未处理的客户端错误的客户端堆栈跟踪)。
通过添加广泛的跟踪和日志记录,我们发现在提供静态资产(特别是样式表)时,这种崩溃一直在发生。我们将我们的静态资产目录列入白名单,不需要身份验证,崩溃就消失了。
我们通过执行以下操作将某些端点配置为不需要身份验证:
var listener = (HttpListener)app.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemeSelectorDelegate = request =>
{
// Options requests should always be anonymous otherwise preflight cors requests
// will fail in Firefox.
if (request.HttpMethod == "OPTIONS")
{
return AuthenticationSchemes.Anonymous;
}
// here we add additional whitelisted paths
var pathsWithoutAuthentication = KnownPaths.AnonymousWhiteList.Concat(KnownPaths.Assets);
return pathsWithoutAuthentication.Any(a => request.RawUrl.ToLower().StartsWith(a))
? AuthenticationSchemes.Anonymous
: AuthenticationSchemes.IntegratedWindowsAuthentication;
};
我一直在处理的应用程序最近开始出现间歇性硬崩溃,我无法解释。为了使这更奇怪,我们同时设置了 AppDomain.CurrentDomain.UnhandledException
和 TaskScheduler.UnobservedTaskException
来捕获此类问题。
通常当出现问题时,以上两个都可以正常工作,但在某些情况下它们不会捕获未处理的异常。使事情变得更糟更糟 导致这种情况的异常是 NRE,这意味着我们无法继续追踪正在发生的事情。
我的第一个想法是,我们在未处理的异常处理程序中的代码可能会抛出异常,因此我们在此处加倍处理异常,但到目前为止,这没有任何区别。我们的日志也无法阐明这一点。
这可能是 webapi 的一个错误 and/or 我们用来托管应用程序的 owin 位,我将尝试增加依赖项以查看是否有帮助,但我不认为这会有什么不同。
有没有办法捕获线程池中发生的未处理异常?是否有某种诊断我们可以启用以获取有关发生这种情况的更多信息?
我已无计可施,如有任何帮助,我们将不胜感激。
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Net.HttpListener.EndGetContext(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.Owin.Host.HttpListener.OwinHttpListener.<ProcessRequestsAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__5(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()
在使用任务时我们不执行 async void
,但我们有一种情况 Task.Run
我们不等待或挂起任务。这是:
Task.Run(() => CleanUpAllExpiredErrors());
此方法清除过期的客户端错误(我们捕获未处理的客户端错误的客户端堆栈跟踪)。
通过添加广泛的跟踪和日志记录,我们发现在提供静态资产(特别是样式表)时,这种崩溃一直在发生。我们将我们的静态资产目录列入白名单,不需要身份验证,崩溃就消失了。
我们通过执行以下操作将某些端点配置为不需要身份验证:
var listener = (HttpListener)app.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemeSelectorDelegate = request =>
{
// Options requests should always be anonymous otherwise preflight cors requests
// will fail in Firefox.
if (request.HttpMethod == "OPTIONS")
{
return AuthenticationSchemes.Anonymous;
}
// here we add additional whitelisted paths
var pathsWithoutAuthentication = KnownPaths.AnonymousWhiteList.Concat(KnownPaths.Assets);
return pathsWithoutAuthentication.Any(a => request.RawUrl.ToLower().StartsWith(a))
? AuthenticationSchemes.Anonymous
: AuthenticationSchemes.IntegratedWindowsAuthentication;
};