我们注意到一些非常小的Web服务调用花费的时间比我们预期的要长.我们做了一些调查并安排了一些定时器,我们将其缩小到创建我们的Entity Framework 6 DbContext的实例.不是查询本身,只是创建上下文.我已经把一些日志记录平均看到创建一个DbContext实例需要多长时间,它似乎是大约50ms.
应用程序预热后,上下文创建速度不慢.应用程序回收后,它开始时间为2-4毫秒(这是我们在开发环境中看到的).上下文创建似乎随着时间的推移而变慢.在接下来的几个小时内,它将爬升到50-80ms的范围并保持平稳.
我们的上下文是一个相当大的代码优先上下文,包含大约300个实体 - 包括一些实体之间的一些非常复杂的关系.我们正在运行EF 6.1.3.我们正在执行"每个请求一个上下文",但对于我们的大多数Web API调用,它只执行一个或两个查询.创建一个60 + ms的上下文,然后执行1ms的查询有点不满意.我们每分钟有大约10k个请求,所以我们不是一个很少使用的网站.
这是我们所看到的快照.时间在MS,最重要的是部署回收app域.每行是4个不同的Web服务器之一.请注意,它并不总是相同的服务器.
我确实采取了内存转储尝试充实了正在发生的事情,这里是堆统计信息:
00007ffadddd1d60 70821 2266272 System.Reflection.Emit.GenericFieldInfo
00007ffae02e88a8 29885 2390800 System.Linq.Enumerable+WhereSelectListIterator`2[[NewRelic.Agent.Core.WireModels.MetricDataWireModel, NewRelic.Agent.Core],[System.Single, mscorlib]]
00007ffadda7c1a0 1462 2654992 System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.Object, mscorlib],[System.Object, mscorlib]][]
00007ffadd4eccf8 83298 2715168 System.RuntimeType[]
00007ffadd4e37c8 24667 2762704 System.Reflection.Emit.DynamicMethod
00007ffadd573180 30013 3121352 System.Web.Caching.CacheEntry
00007ffadd2dc5b8 35089 3348512 System.String[]
00007ffadd6734b8 35233 3382368 System.RuntimeMethodInfoStub
00007ffadddbf0a0 24667 3749384 System.Reflection.Emit.DynamicILGenerator
00007ffae04491d8 67611 4327104 System.Data.Entity.Core.Metadata.Edm.MetadataProperty
00007ffadd4edaf0 57264 4581120 System.Signature
00007ffadd4dfa18 204161 4899864 System.RuntimeMethodHandle
00007ffadd4ee2c0 41900 5028000 System.Reflection.RuntimeParameterInfo
00007ffae0c9e990 21560 5346880 System.Data.SqlClient._SqlMetaData
00007ffae0442398 79504 5724288 System.Data.Entity.Core.Metadata.Edm.TypeUsage
00007ffadd432898 88807 …
Run Code Online (Sandbox Code Playgroud) 我正在尝试构建警报列表并将其添加到TempData
.但是如果我没有重定向它就有效.当我重定向时,它给我500错误.我也在视图中设置了断点,但是当它正确地重定向时,它没有被击中.
ActionMethod
public IActionResult Create(CategoryCreateVM input)
{
if (ModelState.IsValid)
{
var category = mapper.Map<Categories>(input);
categoryBL.Add(category);
List<Alert> alert = new List<Alert>();
alert.Add(new Alert("alert-success", "success message"));
alert.Add(new Alert("alert-danger", "danger message"));
TempData["Alert"] = alert;
return RedirectToAction("Index");
}
return View(input);
}
Run Code Online (Sandbox Code Playgroud)
我如何访问视图.
@{
var alerts = TempData["Alert"] as List<Alert>;
}
@if (alerts != null && alerts.Count > 0)
{
<div class="">
@foreach (var alert in alerts)
{
<div class="alert @alert.AlertClass alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
@alert.Message
</div>
}
</div>
}
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪. …
我想保存通知TempData
并显示给用户。我为此创建了扩展方法,并实现了一个从扩展的类ActionResult
。我需要访问TempData
的override ExecuteResult
法ActionContext
。
扩展方式:
public static IActionResult WithSuccess(this ActionResult result, string message)
{
return new AlertDecoratorResult(result, "alert-success", message);
}
Run Code Online (Sandbox Code Playgroud)
扩展ActionResult类。
public class AlertDecoratorResult : ActionResult
{
public ActionResult InnerResult { get; set; }
public string AlertClass { get; set; }
public string Message { get; set; }
public AlertDecoratorResult(ActionResult innerResult, string alertClass, string message)
{
InnerResult = innerResult;
AlertClass = alertClass;
Message = message;
}
public override void ExecuteResult(ActionContext context)
{ …
Run Code Online (Sandbox Code Playgroud)