我正在使用WebAPI技术对我的Web API执行AJAX调用。
处理该请求的方法如下:
[Route("RenderNotificationsPopup")]
[HttpGet]
public async Task<string> RenderNotificationsPopup(bool responsive = false)
{
return await GetContentAsync(string.Format("RenderNotificationsPopup?responsive={0}", responsive ? 1 : 0));
}
此方法调用GetContentAsync
,使用类HttpClient
执行服务器端调用。
private async Task<string> GetContentAsync(string urlSuffix)
{
using (var client = new HttpClient())
{
return await client.GetStringAsync(string.Format(
"{0}/Header/{1}",
ConfigurationManager.AppSettings["GatewaysHttpRoot"],
urlSuffix));
}
}
一切正常,除非用户在AJAX查询等待WebApi响应时关闭页面。在这种情况下,我收到此错误:
消息:System.Threading.Tasks.TaskCanceledException:任务是 取消。在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() — End of stack trace from previous location where exception was thrown — at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()at System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext()
我可以通过加载页面并在获得AJAX查询的响应之前关闭它来重现此问题,就像在WebApi处理查询之前离开页面一样,它本身也在挣扎。
我在网上搜索并发现有一个与此相关的错误(ASP.NET Web API OperationCanceledException when browser cancels the request)。尽管如此,它显然涉及旧版WebApi软件包,而且我使用的是最新版本。
我的代码中是否存在关于异步/等待模式的错误,还是总是那个讨厌的错误?
非常感谢!
编辑:我尝试了我链接的SO帖子中给出的解决方法(使用类CancelledTaskBugWorkaroundMessageHandler
),我仍然得到TaskCanceledException。
编辑2 :似乎无法避免此问题。是否可以在WebApi应用程序中处理此类异常?
答案 0 :(得分:4)
我使用自己的 ExceptionFilterAttribute 派生类来记录与WebApi应用程序相关的异常,覆盖方法OnException
。
我发现处理异常 TaskCanceledException 的正确方法是覆盖OnExceptionAsync
而不是OnException
并依赖属性IsCancellationRequested
来检测任务的时间被取消了。
以下是我用作错误处理的方法:
public override async Task OnExceptionAsync(HttpActionExecutedContext context, CancellationToken cancellationToken)
{
if (!cancellationToken.IsCancellationRequested)
{
//Handle domain specific exceptions here if any.
//Handle all other Web Api (not all, but Web API specific only ) exceptions
Logger.Write(context.Exception, "Email");
context.Response = context.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "An unhandled exception was thrown.");
}
}
类 Logger 来自企业库应用程序块。
答案 1 :(得分:2)
如果底层客户端连接已死,则取消任务是正常的。您需要处理异常。