锁定静态字段

时间:2010-10-08 03:54:55

标签: c# static locking

我正在维护一个使用公共库的应用程序 有一个类的静态实例(ClassWrapper)。这个类基本上是一个包装器 Microsoft模式和实践的CacheManager(EL的v3.1)

该库托管在Web应用程序中,也存储在Windows服务应用程序中, (两者都是固有的多线程) 应用程序中有很多地方可以调用Add方法 这个包装器反过来调用缓存管理器上的Add来添加一个项目 到缓存管理器。

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

时的线程安全

我不能直接修改库代码来添加同步代码和am 考虑编写这样的辅助方法并修改所有调用站点以使用它 帮助器,而不是直接调用包装器上的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是在主机的整个进程空间中公开的静态实例 (网络应用程序和Windows服务)。

非常感谢任何建议或信任投票。

1 个答案:

答案 0 :(得分:2)

我不确定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有多个实例,那么您只能锁定当前正在使用的实例。