Web API异步任务等待阻塞主线程

时间:2017-03-20 21:07:14

标签: c# multithreading asynchronous async-await asp.net-web-api2

我们有一个三层基础架构(前端是所有Web API 2,中间件接受来自前端的API调用并运行业务逻辑和数据库访问,然后是数据库)

我正在试图找出为什么我的应用程序在我采用中间层时锁定。我们使用Memcached进行所有读取,前端提供缓存数据就好了,但是其中一个调用检查用户是否已登录。在具有一个应用程序池的本地计算机上运行,​​该调用锁定了线程(我认为)并阻止其余的调用做任何事情,直到自动登录呼叫的超时到期。

代码路径如下所示: 致电api / autologin - >前端API调用Client.SendAsync(我们将数据传递给中间件的自定义方法),这会尝试使用HttpClient.SendAsAsync调用中间件,超时为3分钟(可能应该缩短此时间) 我的期望是,这应该在我们等待的时候释放这个帖子。这似乎不是结果。 真正奇怪的是,当中间件关闭时,Client.SendAsync会运行很多次,就像10.我认为这可能是Chrome中的HTTP 2.0,但我切换到了Fiddler,它做了同样的事情。非常奇怪。

所以,两个问题。 1.多次通话有什么用? 2.为什么线程似乎被锁定了?

这是代码。

/// <summary>
/// Auto login user if they have the persistent cookies.
/// </summary>
/// <returns>The groups the logged in user has access to in the form of a 
LoggedInUserData object.</returns>
[Route("api/cms/autologin/")]
[HttpGet]
public async Task<HttpResponseMessage> AutoLogin()
{
    HttpResponseMessage response = await Client.SendAsync(this.Request);
    return this.LoginCacheHelper(response);
}

那叫

public static async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
{
    return await Client.SendAsync<string>(request, null, null, false);
}

哪个电话

public static async Task<HttpResponseMessage> SendAsync<T>(HttpRequestMessage request, T content = null, string route = null, bool isFile = false, TimeSpan? timeout = null) where T : class
{
    // Validate all internal certs.
    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

    // Determine the route and make sure route has a starting forward slash.
    if (!string.IsNullOrWhiteSpace(route) && route.StartsWith("http"))
    {
        // Check to make sure this is a selinc.com domain for security purposes.
        if (Sel.Utils.Validation.UriValidation.IsSelincDomain(route))
        {
            request.RequestUri = new Uri(route);
        }
        else
        {
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
    }
    else
    {
        string middlewareRoute = GetRoute(route, request);

        // Change Uri to middle ware.
        request.RequestUri = new Uri(Config.MwareSiteUrl + middlewareRoute);
    }

    // Remove host header
    request.Headers.Host = string.Empty;

    // Set content of request.
    // File content will be kept on the request as is.
    if (content != null && !isFile)
    {
        request.Content = new ObjectContent<T>(content, new JsonMediaTypeFormatter());
    }
    else if (!isFile)
    {
        request.Content = null;
    }

    // Client handler set use cookies to false which will pass along the current cookies
    HttpClientHandler clientHandler = new HttpClientHandler() { UseCookies = false };

    // The HttpClient object
    HttpClient client = new HttpClient(clientHandler);
    client.Timeout = timeout ?? new TimeSpan(0, 3, 0);

    // Send the request
    return await client.SendAsync(request);
}

在Chrome中添加网络日志的图像以说明行为。 enter image description here 请注意,如果我删除对自动登录的API调用,一切正常。这是该堆栈中唯一一个触及后端的调用。

另请注意:如果我修改SendAsync方法只是返回一个新的HttpResponseMessage(因此不起作用),那么自动登录基本上什么都不做,快速返回并且网站加载应该是,中间件服务器关闭。这只是为了证明它是导致问题的自动登录API调用。自动登录API调用是此时调用SendAsync的唯一方法,因此它是一个有效的测试。

// Send the request
////return await client.SendAsync(request);
return new HttpResponseMessage();

0 个答案:

没有答案
相关问题