0

Web アプリのサービス層ビジネス オブジェクトでキャッシュを行うクラスがあります。負荷分散されたサーバーでコードが実行され、クライアントが 1 台のマシンにアクセスして詳細を更新した後、ブラウザを閉じて再度開き、負荷分散されたソリューションの他のマシンの 1 つで Web サイトにたまたまアクセスした場合、最新の変更は表示されません。

この基本クラスは、People などの他のビジネス オブジェクトに継承されます。負荷分散された環境の他のサーバーでこのキャッシュされたオブジェクトを更新して、クライアントが常に最新のものを参照できるようにする方法はありますか?

   public abstract class CacheStore<T> where T:IComparable, new()
    {
        private class CacheItem
        {
            public T Item
            {
                get;
                set;
            }

            public DateTime Expires
            {
                get;
                set;
            }
        }

        private List<CacheItem> theCache = new List<CacheItem>();

        public abstract TimeSpan Lifetime
        {
            get;
        }

        public int CountAll
        {
            get
            {
                return theCache.Count();
            }
        }

        public int CountExpired
        {
            get
            {
                return theCache.Count(i => i.Expires < DateTime.Now);
            }
        }

        public void Add(T item)
        {
            CacheItem i = (from c in theCache where (c.Item.CompareTo(item) == 0) select c).FirstOrDefault();
            if (i != null)
            {
                if (i.Expires < DateTime.Now)
                {
                    theCache.Remove(i);
                    i = null;
                }
            }

            if (i == null)
            {
                theCache.Add(new CacheItem()
                {
                    Expires = DateTime.Now + Lifetime,
                    Item = item
                });
            }
        }

        public IEnumerable<T> Filter(Func<T, bool> predicate)
        {
            return (from c in theCache where c.Expires > DateTime.Now select c.Item).Where(predicate);
        }

        public void MarkAsExpired(Func<T, bool> predicate)
        {
            var markAsExpired = from c in theCache 
                                where this.Filter(predicate).Contains(c.Item) 
                                    select c;
            foreach (CacheItem ci in markAsExpired)
            {
                ci.Expires = DateTime.Now.Subtract(TimeSpan.FromSeconds(1));
            }
        }
    }
}
4

2 に答える 2

1

ロイドの答えは基本的にそれをカバーしています。

.NET アプリケーションで独自のキャッシュをロールするのは少し珍しいことです。一般に、フレームワークに組み込まれているキャッシュを使用します。概要についてはASP.NET キャッシュ、およびSystem.Web.Caching 名前空間を参照してください。それを行っていた場合、たとえば、SqlCacheDependencyを使用して、データベースの変更時にキャッシュされたデータを無効にすることができます。

ただし、負荷分散環境の場合は、Lloyd が推奨するように集中型キャッシュを使用する方がよいでしょう。Microsoft ソリューションを使い続けたい場合は、AppFabricが頼りになるオプションです。

于 2013-07-25T23:30:28.703 に答える