-1

我在一个接受三个参数的单例类中有一个通用的缓存访问方法。

  1. 一个委托(没有参数的 void 返回类型)
  2. 缓存标签
  3. 旨在停止并发缓存设置的锁定对象

见下文:

protected delegate T GetDataMethod<T>();


protected override D GetCachedData<D>(GetDataMethod<D> dataAccessMethod, string cachelabel, object lockObject)
    {

        if (MemoryCache.Default[cachelabel] == null)
        {
            lock (lockObject)
            {
                //Inside the lock, test once again in case the cache object has been set already
                if (MemoryCache.Default[cachelabel] == null)
                {
                    umbraco.BusinessLogic.Log.Add(umbraco.BusinessLogic.LogTypes.Debug, -10, cachelabel + " inside lock, cache empty");

                    D data = default(D);


                        try
                        {
                            data = dataAccessMethod();
                        }
                        catch (Exception ex)
                        {

                          //Logging                               
                        }



                    MemoryCache.Default.Add(cachelabel, data, GetCacheItemPolicy());
                }
            }
        }

        return (D)MemoryCache.Default[cachelabel];
    }

对于每个缓存设置为静态只读对象的数据集合,我都有单独的锁定对象。但是,通过将它们传递给方法,它们的范围仅存在于方法中,因此锁变得无关紧要。

我不能使用“ref”,因为你不能通过 ref 传递静态对象,因为周围的类是一个单例,如果我使锁定对象非静态有关系吗?如果可以,任何人都可以推荐一种更好的方法来处理它而不使用基于 cacheLabel 的 switch 语句吗?

编辑:为了清楚起见,方法足迹:

 protected override D GetCachedData<D>(GetDataMethod<D> dataAccessMethod, string cachelabel, ref object lockObject)

由于锁定对象是静态的,因此不起作用。我想问题真的是 - 在单例中,锁对象是否需要是静态的才能线程安全?(是的,这是一个线程安全的单例)

4

1 回答 1

1

我认为您错过了ref关键字的重点-您不需要它。您正在传递一个object已经是引用类型的。添加ref关键字将使其成为对引用的引用。

于 2013-03-31T09:25:34.297 回答