为什么 ASP.NET 中的静态变量锁不起作用?

问题描述 投票:0回答:1

函数

GetYYY()
是从 ASP.NET 基页调用的。因此,多个用户可以同时发生这种情况。
_data
应该只初始化一次。但是,该锁不会锁定静态列表。从我们的日志中,
log.Debug
执行了两次并记录了 2 个值(请参阅下面的评论)。为什么锁不起作用?

public class XXX
{        
    private static List<YYY> _data = new List<YYY>();

    public List<YYY> GetYYY()
    {           
        lock (_data)
        {
            if (_data.Count > 0)
            {
                return _data; 
            }

            _data = new List<YYY>();

            try
            {
                var query = @" SELECT ...";

                using (var dab = GetDataAccessBlock())
                {
                    OracleDataReader reader = dab.ExecuteSQLAsReader(query);

                    while (reader.Read())
                    {
                        _data.Add(new YYY
                                      {
                                          P1 = reader["P1"].ToString(),
                                          P2 = ...
                                      });
                    }

                    log.Debug(_data.Count + " values are returned. this should be called only once when app restarts"); //this logs twice with wrong numbers 863 and 787... when there is only one user, it should be 432
                }
            }
            catch (Exception ex)
            {
                log.Error("..." );
            }

            return _data;
        }
    }
}
c# asp.net locking
1个回答
0
投票

必须对一个对象进行锁定,该对象的生命周期要长于您要保护的数据。

您所采用的锁位于一个within

GetYYY()
可变的对象上,因此没有保证,并且因此肯定是一个错误。正如评论中所表达的,锁定其他东西。锁定该调用范围之外的内容,并在调用期间持续存在。

虽然不是最好的方法,但您仍然可以锁定列表,但前提是您创建它一次,并更改您的语义在调用中以在添加之前清除列表。这样,您的列表在通话中仍然存在,但其内容可以更改。

也就是说......最好使用类范围的外部锁作为机制。

© www.soinside.com 2019 - 2024. All rights reserved.