好的一些背景。我有类似的东西:
class ConnectionFactory
{
public IConnection Connect()
{
if (User.IsAuthenticated) {
return InternalConnect(User.Username, null);
}
return null;
}
public IConnection Connect(string username, string password)
{
return InternalConnect(username, password);
}
private IConnection InternalConnect(string username, string password)
{
IConnection connection;
var cacheKey = Session[CacheKeySessionKey] as string;
if (!string.IsNullOrEmpty(cacheKey)) {
connection = HttpCache[cacheKey] as IConnection;
}
if (!IsGoodConnection(connection) {
connection = MakeConnection(username, password); // very costly
cacheKey = Session[CacheKeySessionKey] = // some key
HttpCache[cacheKey] = connection;
}
return connection;
}
private bool IsGoodConnection(IConnection conn)
{
return conn != null && conn.IsConnected;
}
}
我目前遇到了一个并发问题,其中 Connect()
被多次调用并为每个请求创建多个 IConnection
。我只需要一个。它正在使用 IoC 容器注入(inject)到各种实例中。 MakeConnection
非常昂贵,因为它启动了一个 WCF channel 。
我的问题是:如何锁定 InternalConnect
调用每个 session ?我不认为锁定每个请求 是正确的方法,因为每个用户可能会发生多个请求。我当然不想为每个调用都锁定,因为这会导致性能不佳。
我认为这样做是个坏主意:
lock(Session.SessionID)
{
// Implementation of InternalConnect
}
注意:用户名和密码重载是我仅在登录时调用的。
最佳答案
这只是未经测试的代码,来 self 的脑海,但它可能有效?
// globally declare a map of session id to mutexes
static ConcurrentDictionary<string, object> mutexMap = new ConcurrentDictionary();
// now you can aquire a lock per session as follows
object mutex = mutexMap.GetOrAdd(session.SessionId, key => new object());
lock(mutex)
{
// Do stuff with the connection
}
您需要找到一种方法从 mutexMap
中清除旧 session ,但这应该不会太困难。
关于c# - 每个 ASP.NET session 锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9311875/