【问题标题】:Web Api - Really slow response when performing few requests at the same timeWeb Api - 同时执行几个请求时响应真的很慢
【发布时间】:2018-09-05 23:15:47
【问题描述】:

我有一个 Web API C# 项目。我注意到,当一起向控制器发送几个请求(很少甚至 7-10 个)时,一些请求需要很长时间(5-7 秒)。单独发送每个请求时,每个请求耗时不到 200ms。我正在向我的本地主机(开发环境)发送请求,因此服务器上不应该有任何延迟或大量使用。

我在 global.asax 中添加了这段代码,以便查看每个请求需要多长时间。

//Global asax

 private Dictionary<string, StopWatch> urlTimers = new Dictionary<string, StopWatch>();
    void Application_BeginRequest(object sender, EventArgs e)
    {
        HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current);
        var requestedUrl = currentContext.Request.RequestContext.HttpContext.Request.RawUrl;
        var urlWithoutQueryParams = requestedUrl.Split('?')[0];
        if (urlWithoutQueryParams.StartsWith("/controller"))
        {
            var stopWatch = new StopWatch();
            stopWatch.Start(urlWithoutQueryParams);
            urlTimers[urlWithoutQueryParams] = stopWatch;
        }

     
    }

    void Application_EndRequest(object sender, EventArgs e)
    {
        HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current);
        var requestedUrl = currentContext.Request.RequestContext.HttpContext.Request.RawUrl;
        var urlWithoutQueryParams = requestedUrl.Split('?')[0];
        if (urlWithoutQueryParams.StartsWith("/controller"))
        {
            var stopWatch = urlTimers[urlWithoutQueryParams];
            if (stopWatch != null)
            {
                stopWatch.Stop();
            }
        }
    }

当使用提琴手提交 10 个请求时,我收到以下内容

所有请求都返回少量数据,所以这也不应该是问题。 10 个请求花费这么多时间是没有意义的。任何帮助将不胜感激。

【问题讨论】:

    标签: c# asp.net asp.net-web-api


    【解决方案1】:

    我会假设这还不是 MVC 6 Web Api(存在 Global.asax 和所有),而是 MVC 5 或更低版本。人们在 MVC 5 Web API 中忘记的一件事是 SessionState。 一些关于此的简短博客:

    简而言之就是这样:

    启用 SessionState 后,每个用户会话一次只处理一个请求。 在您的情况下,这意味着:

    • GetAsKeyValuePairs 已处理
    • 然后处理 GetTranslationManagmentData
    • 然后处理 IsCaptionsExist
    • ...

    它们都是同时请求的,因此它们具有相同的开始时间。 然而,请求的结束时间取决于先前请求所需的时间 + 它自己的处理时间。这会导致样本中每次调用的时间增加。

    如果您的操作不访问会话信息,您可以“安全地”在控制器上添加 [SessionState(SessionStateBehavior.ReadOnly)] 属性(请参阅博客)。 这将导致同时处理呼叫。只是不要在更改会话信息的控制器上使用它。

    【讨论】:

    • 非常感谢您的帮助。你真的救了我。使用 [SessionState(SessionStateBehavior.ReadOnly)] 我还能阅读会话吗?如果我理解正确,现在我会为每个请求获取会话的克隆?
    • 您仍然可以阅读它们(甚至更改它们,但不要,不值得它带来的问题)。像这样看。正常的会话状态行为会在请求开始时锁定会话,并在结束时将其解锁。使用只读,没有锁。 2 次调用可能会更改相同的数据,因此只能读取它。将 sessionstate 视为用户会话中的单例。
    • 非常感谢。真的帮了我
    猜你喜欢
    • 2016-08-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 2013-12-08
    • 2021-06-25
    • 2017-09-26
    • 2023-04-05
    相关资源
    最近更新 更多