2010-06-21 Marek Habersack <mhabersack@novell.com>
[mcs.git] / class / System.Web.Mvc / System.Web.Mvc / ReaderWriterCache`2.cs
blobfaf4fdaf9d02a30849614ae9e72a537851f19a50
1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * This software is subject to the Microsoft Public License (Ms-PL).
6 * A copy of the license can be found in the license.htm file included
7 * in this distribution.
9 * You must not remove this notice, or any other, from this software.
11 * ***************************************************************************/
13 namespace System.Web.Mvc {
14 using System;
15 using System.Collections.Generic;
16 using System.Threading;
18 internal abstract class ReaderWriterCache<TKey, TValue> {
20 private readonly Dictionary<TKey, TValue> _cache;
21 private readonly ReaderWriterLock _rwLock = new ReaderWriterLock();
23 protected ReaderWriterCache()
24 : this(null) {
27 protected ReaderWriterCache(IEqualityComparer<TKey> comparer) {
28 _cache = new Dictionary<TKey, TValue>(comparer);
31 protected Dictionary<TKey, TValue> Cache {
32 get {
33 return _cache;
37 protected TValue FetchOrCreateItem(TKey key, Func<TValue> creator) {
38 // first, see if the item already exists in the cache
39 _rwLock.AcquireReaderLock(Timeout.Infinite);
40 try {
41 TValue existingEntry;
42 if (_cache.TryGetValue(key, out existingEntry)) {
43 return existingEntry;
46 finally {
47 _rwLock.ReleaseReaderLock();
50 // insert the new item into the cache
51 TValue newEntry = creator();
52 _rwLock.AcquireWriterLock(Timeout.Infinite);
53 try {
54 TValue existingEntry;
55 if (_cache.TryGetValue(key, out existingEntry)) {
56 // another thread already inserted an item, so use that one
57 return existingEntry;
60 _cache[key] = newEntry;
61 return newEntry;
63 finally {
64 _rwLock.ReleaseWriterLock();