"返回Json(myObject);"?

时间:2017-01-12 14:33:24

标签: c# asp.net

我在我的申请中观察到一种非常奇怪的行为 请看这个:
enter image description here
给定页面通过ajax实现5个API操作。奇怪的是,当以同时的方式执行时,响应时间的总和比顺序的慢大约10-100倍。
在我的应用程序中,我有2种类型的遥测日志。一个是MS本身提供的应用程序洞察,以及一个处理BeginRequestEndRequest事件的基本HttpModule记录所花费的时间。
问题是来自两者和提琴手的信息不一致。 httpModule日志与fiddler表示始终匹配,但在顺序发出请求时,应用洞察匹配。
我从应用程序见解中获得的数据让我相信请求总是顺序的。

寻找可能性和解释,我已经消除了与数据库事务相关的问题(因为那些是读取操作,没有发生死锁),代码锁定(没有锁定发生)和其他因为直到"返回Json (东西);"行为是100%一致的。现在,我只有一个地方可以查看:finally块与EndRequest事件处理之间的位置。

那么,那里会发生什么?造成这种情况的原因是什么?"滞后"?!?

额外信息:
Application Insights日志记录如下:

public JsonResult DoSomething(int id)
    {
        #region Trace
        Stopwatch st = Stopwatch.StartNew();
        RequestTelemetry reqTel = new RequestTelemetry();
        TraceTelemetry traceTelemetry = new TraceTelemetry();
        traceTelemetry.Message = "Doing Somthing";
        traceTelemetry.SeverityLevel = SeverityLevel.Verbose;
        _logger.TrackTrace(traceTelemetry);
        #endregion
        try
        {
            var something = Work();
            #region Trace
            traceTelemetry = new TraceTelemetry();
            traceTelemetry.Message = "Returning Work";
            traceTelemetry.SeverityLevel = SeverityLevel.Verbose;
            _logger.TrackTrace(traceTelemetry);
            #endregion
            return Json(something);
        }
        catch
        {
            return Json(0);
        }
        finally
        {
            #region Trace
            st.Stop();
            reqTel.Duration = st.Elapsed;
            reqTel.Name = "DoSomething";
            reqTel.Url = HttpContext.Request.Url;
            reqTel.Properties.Add("Message", "Finally Block for DoSomething");
            reqTel.Properties.Add("TimeStamp", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            _logger.TrackRequest(reqTel);
            #endregion
        }
    }

1 个答案:

答案 0 :(得分:1)

您的观察是正确的,原因是ASP.NET中的每个请求都会锁定请求的会话对象。换句话说,只有一个请求正在处理特定会话而其他会话正在排队。

有一种解决方法 - 您必须指定特定请求可以是服务器而无需访问会话(或具有只读访问权限)。对于ASP.NET MVC,您可以在控制器上使用值SessionStateAttributeReadOnly的{​​{1}}来实现此目的

Disable

如果您需要对会话进行写访问,则无法解决此问题。