C# 使用Session.SyncRoot锁定每个会话有什么危险?
如果在ASP.NET MVC应用程序中两个请求非常接近,则我有以下代码的竞争条件:C# 使用Session.SyncRoot锁定每个会话有什么危险?,c#,asp.net,asp.net-mvc-3,session,thread-safety,C#,Asp.net,Asp.net Mvc 3,Session,Thread Safety,如果在ASP.NET MVC应用程序中两个请求非常接近,则我有以下代码的竞争条件: var workload = org.Workloads.SingleOrDefault(p => ...conditions...); if (workload == null) { workload = org.CreateWorkload(id); } workload和org是EntityFramework对象。调用CreateWorkload会向数据库中的Workload表中添加一行。(
var workload = org.Workloads.SingleOrDefault(p => ...conditions...);
if (workload == null) {
workload = org.CreateWorkload(id);
}
workload
和org
是EntityFramework对象。调用CreateWorkload
会向数据库中的Workload表中添加一行。(我们确实应该在表上使用一个唯一的约束来强制执行这一点,但我现在不能这样做,因为表中有一些脏数据。)当SingleOrDefault
遇到多个满足条件的行时,对包含此代码的Action方法的后续调用会引发异常
为了解决这个问题,我想锁定这些代码行。我不希望每个请求都使用静态锁对象完成,因为这会降低每个用户的站点速度。我想做的是用来锁。即
Workload workload;
lock (Session.SyncRoot)
{
workload = org.Workloads.SingleOrDefault(p => ...conditions...);
if (workload == null) {
workload = org.CreateWorkload(id);
}
}
但是,我不是ASP.NET专家,文档和ReSharper中显示了一些警告标志,即它可能抛出NotImplementedException或为null。然而,测试表明,这种方法效果很好
那么,ASP.NET专家们,使用Session.SyncRoot进行此操作有哪些风险?或者,如果Session.SyncRoot“非常危险”,我可以在会话启动时在会话集合中分配一个锁对象来执行相同的操作吗?只有在使用实现了
HttpSessionStateBase
的自定义会话类,但没有覆盖SyncRoot
属性来执行除抛出NotImplementedException之外的操作时,才会存在这种危险。
类和
类实现并重写了SyncRoot
方法。因此,只要您通过HttpSessionStateWrapper
或HttpSessionState
类而不是自定义类访问会话,就可以正常工作