webapi bug: System.OperationCanceledException异常处理

asp.net webapi的过滤器 ExceptionFilterAttribute 捕获一个异常消息如下:.

错误跟踪: 在 System.Threading.CancellationToken.ThrowIfCancellationRequested() 在 System.Web.Http.Filters.ActionFilterAttribute.d__5.MoveNext()

--- 引发异常的上一位置中堆栈跟踪的末尾

--- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 在 System.Web.Http.Filters.ActionFilterAttribute.d__0.MoveNext()

--- 引发异常的上一位置中堆栈跟踪的末尾

--- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 在 System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()

--- 引发异常的上一位置中堆栈跟踪的末尾

--- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 在 System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext()

关于异常的疑难解答:System.OperationCanceledException

如果在 UICancelOption 设置为 ThrowException 的情况下执行某一操作,然后取消了该操作,则将引发 OperationCanceledException。

相关提示

  • 如果您不希望引发此异常,请将 OperationCanceledException 设置为 DoNothing。

  • UICancelOption 的默认值为 ThrowException。如果您不希望当用户取消操作时引发此异常,请将枚举值设置为 DoNothing。

https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/ms164920(v=vs.100)

解决办法:

public class CancelledTaskBugWorkaroundMessageHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
        // Try to suppress response content when the cancellation token has fired; ASP.NET will log to the Application event log if there's content in this case.
        if (cancellationToken.IsCancellationRequested)
        {
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }
        return response;
    }
}
config.MessageHandlers.Add(new CancelledTaskBugWorkaroundMessageHandler());