使用异步/等待模式执行服务器端调用(错误:TaskCanceledException)

问题描述 投票:0回答:2

我正在使用 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()
在 System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()

--- 从先前抛出异常的位置开始的堆栈跟踪结束 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (任务 任务)
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)
在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
在 System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()

--- 从先前抛出异常的位置开始的堆栈跟踪结束 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (任务 任务)
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)
在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
在 System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext()

我可以通过在获得 AJAX 查询的响应之前加载页面并关闭它来重现此问题,就像在 WebApi 处理查询时离开页面本身很困难一样。

我在网上搜索,发现有一个与此相关的错误(当浏览器取消请求时,ASP.NET Web API OperationCanceledException)。尽管如此,它显然涉及旧版本的 WebApi 包,而我正在使用最新版本。

我在代码中是否犯了关于异步/等待模式的错误,或者它总是那个令人讨厌的错误?

非常感谢!

编辑:我尝试了我链接的SO帖子中给出的解决方法(使用类

CancelledTaskBugWorkaroundMessageHandler
),但我仍然得到TaskCanceledException。

编辑2:似乎这个问题无法避免。是否可以在WebApi应用程序中处理此类异常?

c# .net asynchronous asp.net-web-api asp.net-web-api2
2个回答
5
投票

我使用自己的派生类 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 来自企业库应用程序块。


2
投票

如果底层客户端连接断开,任务被取消是正常的。您需要处理异常。

© www.soinside.com 2019 - 2024. All rights reserved.