我正在维护一个使用通用库的应用程序
有一个类的静态实例(ClassWrapper)。此类基本上是围绕
Microsoft模式和实践的CacheManager(EL v3.1)

该库托管在Web应用程序和Windows Service应用程序中,
(两者本质上都是多线程的)
应用程序中有很多地方可以在其上调用Add方法
该包装器依次调用缓存管理器上的“添加”以添加项目
到缓存管理器。

据我了解,CacheManager不是线程安全的,而CacheWrapper不是
执行任何锁定以确保Add调用中的线程安全。

我无法直接修改库代码以添加同步代码,并且
考虑编写这样的辅助方法,并修改所有呼叫站点以使用此方法
帮助程序,而不是直接在包装器上调用添加。

class CacheHelper
{
    private static object _syncLock = new object();

    public static void Add<T>(CacheWrapper wrapper, string key, T value, int expireInMins)
    {
        lock (_syncLock)
        {
            wrapper.Add(key, value, expireInMins);
        }
    }
}


您看到这种方法有什么问题吗?我有点烦,因为CacheWrapper是静态的,因此_syncLock本质上也是静态的。
我对锁定静态对象感到有些不安,但是自从
CacheWrapper是一个静态实例,在主机的整个处理空间中公开
(Web应用程序和Windows服务)。

任何建议或信任投票将不胜感激。

最佳答案

我不确定CacheManager是否不是线程安全的。选中this MSDN article-它明确指出:


  通过
  CacheManager对象是线程安全的。


现在,在实现时,我不确定为什么要将CacheWrapper实例传递给方法。 CacheWrapper是静态实例,您可以直接引用它,例如

class CacheHelper
{

    private static CacheWrapper GetWrapper()
    {
       return [Lib Namespace].[Class Name].[Field Name referring to CacheWrapper];
    }


    public static void Add<T>(string key, T value, int expireInMins)
    {
        var wrapper = GetWrapper();
        lock (wrapper)
        {
            wrapper.Add(key, value, expireInMins);
        }
    }

    ...


同样,GetWrapper是一种工厂方法,实现可以更改-它可以使用静态委托来获取CacheWrapper实例,或者使用依赖项注入来获取对CacheWrapper的引用。

此处的另一个优点是,如果CacheWrapper有多个实例,那么您将仅锁定当前使用的实例。

关于c# - 锁定静态字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3887583/

10-16 20:33