假设我在Base类中有一个静态字段“ShoppingCart”。此字段由数据库填充。
public static Cart { get {
if (cart == null)
cart = repo.GetCart(userId);
return cart;
}}
public class Process1: MyBase {
Cart.Name = UserName // do some processing
}
如何在MVC应用程序中工作?,假设2个人调用Process1,每个人都有自己独立的Cart实例(即使它是静态的吗?)或者来自(另一个浏览器)的第二个调用会覆盖Cart的实例以前的?
答案 0 :(得分:2)
不,会发生的事情是,第一个点击 getter 会初始化整个静态字段,第二个可能会也可能不会覆盖它再次初始化它。
为了避免这种情况,您需要使用lock
(即Monitor
)实现基本线程同步:
private static readonly object _syncLock = new object();
private static Cart _cart;
public static Cart Cart
{
get
{
lock(_syncLock)
{
if (_cart == null)
_cart = repo.GetCart(userId);
}
return _cart;
}
}
由于静态字段在所有线程中共享,这意味着所有请求将在您的案例中共享相同的购物车。
由于HTTP是无状态协议,因此您应该将服务器端代码实现为无状态。您应该根据给定请求中的关联用户标识符并在其开头的某个位置按请求获取购物车,访问您的存储库并将用户的购物车设置为控制器属性。
在ASP.NET MVC和WebAPI中,这是使用操作过滤器实现的,它允许您在控制器操作执行之前和之后执行某些操作。这是一篇关于在官方ASP.NET站点上发布的主题的好文章:Understanding Action Filters