我正在维护一个使用公共库的应用程序 有一个类的静态实例(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服务)。
非常感谢任何建议或信任投票。
答案 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有多个实例,那么您只能锁定当前正在使用的实例。