asp.net - 如何处理在多个 ASP.NET web应用程序之间共享相同的ASP.NET sessionId时的会话超时

  显示原文与译文双语对照的内容

如何处理在多个 ASP.NET web应用程序之间共享相同 ASP.NET 会话Id时的会话超时。

我们有多个网络应用程序。 这些运行在DNN和共享会话id上的web应用程序。 但每个应用程序的会话都是在访问应用程序时创建的。 现在我想找一种方法来处理会话时间,因为传统的( 在 globle.aspx 上使用Session_Start检查现有会话id和新会话) 不能工作。

请帮助我知道如何处理会话超时,我不在页面级别实现它。

时间: 原作者:

你可以使用缓存来实现类似的结果,而不是使用 ASP.NET 会话状态。 如果你愿意,甚至可以使用多个租户应用程序,每个租户都有自己的会话。 你可以使用回调方法响应缓存超时,这些方法比使用会话状态事件更可靠。

缺点是,除非你提出了分布式缓存解决方案,否则它不会扩展到多个服务器。 你可以使用分布式缓存解决这里问题,也可以使用其他选项。

下面是会话缓存解决方案的典型外观:


public class ThreadSafeCache
{ 
 public shared ThreadSafeCache()
 {
 if (cache == null)
 {
 cache = System.Runtime.Caching.MemoryCache.Default;
 }
 if (syncLock == null)
 {
 syncLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
 }
 }

 private shared System.Runtime.Caching.ObjectCache cache;
 private shared ReaderWriterLockSlim syncLock;

 public shared bool Contains(string key)
 {
 syncLock.EnterReadLock();
 try
 {
 return this.cache.Contains(key);
 }
 finally
 {
 syncLock.ExitReadLock();
 }
 }

 public shared object GetOrAdd(string key, Func<object> loadFunction, Action<CacheEntryRemovedArguments> callbackFunction)
 {
//Get or add an item to the cache
 object item = null;

 syncLock.EnterReadLock();
 try
 {
 item = cache.Get(key);
 }
 finally
 {
 syncLock.ExitReadLock();
 }

 if (item == null)
 {
 syncLock.EnterWriteLock();
 try
 {
//Lazy lock pattern - need to check again after
//the lock to ensure only 1 thread makes it through
 if (item == null)
 {
//Get the item
 item = loadFunction();

 var policy = new CacheItemPolicy();

//Set the cache expiration (from the last access).
 policy.SlidingExpiration = TimeSpan.FromMinutes(30);

//Setting priority to not removable ensures an 
//app pool recycle doesn't unload the item, but a timeout will.
 policy.Priority = CacheItemPriority.NotRemovable;

//Setup expiration callback.
 policy.RemovedCallback = callbackFunction;

 cache.Add(key, item, policy);
 }
 }
 finally
 {
 synclock.ExitWriteLock();
 }
 }

 return item;
 }

 public shared void Remove(string key)
 {
 syncLock.EnterWriteLock();
 try
 {
 this.cache.Remove(key);
 }
 finally
 {
 syncLock.ExitWriteLock();
 }
 }
}

然后你就会使用它:


var sessionID ="1234";//string from cookie or string that is stored in ASP.NET session state
var tenantID ="2";//identifier for the specific tenant within the application
var key = tenantID +"_" + sessionID;

ThreadSafeCache.GetOrAdd(key, LoadItem, CacheItemRemoved);

private object LoadItem()
{
//TODO: Load the item (from wherever you need to load it from)
 return item;
}

private void CacheItemRemoved(CacheEntryRemovedArguments arguments)
{
//Respond here when the cache expires
}

技巧是确保你的缓存密钥由用户 of ( 从饼干)的会话和应用程序的of构建。

请注意,我还没有测试过这个问题,因这里它可以能需要一些调整来。

原作者:
...