未处理的任务异常没有被捕获

4
我一直在开发的应用程序最近开始出现间歇性的硬崩溃,但我无法解释原因。更奇怪的是,我们都设置了 AppDomain.CurrentDomain.UnhandledExceptionTaskScheduler.UnobservedTaskException 以捕获此类问题,通常情况下,当某些事情出错时,上述两个方法都能正常工作,但在某些情况下,它们却不能捕获未处理的异常。更糟糕的是,导致这种情况的异常是NRE,这意味着我们没有任何追踪异常的线索。
我的第一个想法是,也许我们在未处理的异常处理程序中的代码可能会抛出异常,所以我们加倍处理了异常,但到目前为止还没有任何改变。我们拥有的日志也无法阐明这一点。
这可能是WebAPI和/或我们使用来托管应用程序的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());

这个方法清理过期的客户端错误(我们在未处理的客户端错误上捕获客户端堆栈跟踪)。

@ScottChamberlain 我不确定是什么原因导致的,可能是我们的任何控制器或者可能是 Signalr hubs... 这些是唯一使用 HttpListener 的东西,但我们有很多这样的东西。 - jonnii
@ScottChamberlain 我们没有异步空方法,所有的方法要么返回一个 Task,要么返回一个 Task<T>。不过有几个地方我们调用了 Task.Run - jonnii
你是保留Task.Run返回的任务并等待任务完成,还是采用“fire and forget”的方式?如果使用“fire and forget”,请提供一个使用示例。(我也要删除我的旧评论以清理空间) - Scott Chamberlain
我会更新问题。 - jonnii
@ScottChamberlain 完成 - jonnii
显示剩余2条评论
1个回答

3
通过添加详细的跟踪和日志记录,我们发现这个崩溃问题在提供静态资源时会一直发生,特别是样式表。我们将静态资源目录列入白名单,无需进行身份验证,这个崩溃问题就解决了。
我们通过以下方式配置某些端点不需要身份验证:
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;
};

1
绝对不知道为什么或者如何发生的,只是找到了一种解决方法并继续前进。 - jonnii
我们正在按照你发布的答案进行操作,但仍然出现了错误。虽然在过去两年中数百万次请求中只有一次出错,但我倾向于将其归咎于小精灵。不幸的是,这导致了一个严重的、无法恢复的崩溃。 - EricRRichards
1
@EricRRichards 嗯,这对我们没有解决问题,但我们几乎每天都会遇到它,目前还不知道原因 :( - Jon
@Jon,你尝试更新一下NuGet引用了吗?也许你的某些引用已经过时了。 - jonnii
1
有人解决了这个问题吗?目前我们正在使用所有Microsoft.OWIN.*的v3.0.0版本,它正在困扰着我们。 - Alastair Maw
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接