dax*_*axu 4 c# windbg stackexchange.redis
我认为静态对象是跨多个线程共享的.但是,我在我的一个网站上遇到了一个高CPU问题,所以我采取了一个windbg转储并且非常惊讶,我看到了:
我们可以看到有一个名为ConnectionMultiplexer的类的10个实例.但我的代码将ConnectionMultiplexer创建为静态对象.这应该意味着只为所有线程创建一个实例.那么windbg怎么会出现多个实例呢?
这是我创建redis连接的代码
public static class CacheConnection
{
private static StackExchangeRedisCacheClient _newconnectionDb;
public static StackExchangeRedisCacheClient NewConnectionDb
=> _newconnectionDb ?? (_newconnectionDb = NewRedisConnection());
private static IDatabase _connectionDb;
public static IDatabase ConnectionDb => _connectionDb ?? (_connectionDb = RedisConnection());
private static StackExchangeRedisCacheClient NewRedisConnection()
{
var serializer = new NewtonsoftSerializer();
return new StackExchangeRedisCacheClient(Connection, serializer);
}
private static IDatabase RedisConnection()
{
var cacheDatabase = Connection.GetDatabase();
return cacheDatabase;
}
public static ConnectionMultiplexer Connection => LazyConnection.Value;
private static readonly Lazy<ConnectionMultiplexer> LazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(
System.Configuration.ConfigurationManager.AppSettings["CacheConnectionString"]), LazyThreadSafetyMode.PublicationOnly);
}
Run Code Online (Sandbox Code Playgroud)
ConnectionMultiplexer实际上是一个readonly(get)属性,使用新的C#7 short syntax =>,LazyConnection.Value每次访问它时都会返回.
然后你使用LazyThreadSafetyMode.PublicationOnlyMSDN中定义的那个(https://msdn.microsoft.com/en-us/library/system.threading.lazythreadsafetymode(v=vs.110).aspx)
当多个线程尝试同时初始化Lazy实例时,允许所有线程运行初始化方法(或者如果没有初始化方法,则运行默认构造函数).完成初始化的第一个线程设置Lazy实例的值.除非初始化方法在这些线程上抛出异常,否则该值将返回到同时运行初始化方法的任何其他线程.由竞争线程创建的任何T实例都将被丢弃.如果初始化方法在任何线程上抛出异常,则异常将从该线程上的Lazy.Value属性传播出去.该异常未缓存.IsValueCreated属性的值保持为false,并且后续调用Value属性(由抛出异常的线程或其他线程)导致初始化方法再次运行.如果初始化方法以递归方式访问Lazy实例的Value属性,则不会抛出异常.
这意味着如果多个线程试图在同一时间访问它们,它们将各自创建自己的实例,尽管您最终将使用创建的第一个线程而不管线程(但实例仍然存在).
你真正需要的是LazyThreadSafetyMode.ExecutionAndPublication
但这可能会引入死锁.
如果你不需要这个懒惰你可以使用Jon Skeet在他的书C#In Depth中提出的单例模式实现之一
你可以在http://csharpindepth.com/Articles/General/Singleton.aspx找到它们
| 归档时间: |
|
| 查看次数: |
296 次 |
| 最近记录: |