2011-11-29 2 views
0

나는 많은 곳은 ASP.net 4.0의 새로운 기능을 말했다 읽고, 코드는 다음과 같습니다ASP.Net 4.0의 DiskCacheProvider가 실제로 있습니까?

<caching> 
     <outputCache defaultProvider="AspNetInternalProvider"> 
      <providers> 
       <add name="DiskCache" 
        type="test.OutputCacheEx.DiskOutputCacheProvider, DiskCacheProvider"/> 
      </providers> 
     </outputCache> 
    </caching> 

어쨌든, 나는 밖으로 내부에 사용하는 코드를 변경하지 작동 얻을 수 없습니다. 나는 asp.net와 함께 출하하는 AspNetInternalProvider가 1 캐시 공급자를 찾을 수 없습니다.

그래서 DiskOutputCacheProvider가 실제로 있습니까? 그렇다면 사용 방법.

또한 Azure에서 사용해야하므로 캐시 캐시 설정에 디스크 캐시가 있어야합니다.

누구든지 하늘을위한 디스크 캐시 솔루션 (LocalResources.LocalStorage 사용 여부에 관계없이)이 있으면 무료 또는 유료로 나와 공유하십시오. 감사.

+0

DiskOutputCacheProvider 클래스를 게시 할 수 있습니까? –

답변

1

DiskCacheOutputProvider는 .net 4.0에 포함되어 있지 않습니다. 그러나 .net 4.0 캐싱을 확장하고 나만의 캐싱을 만들 수 있습니다. 이것이 어떻게 수행되는지에 대한 몇 가지 예가 온라인에 있습니다. 그냥 샘플 코드 등 사용에주의 프라임 타임에 대한 준비가되어 있지

http://weblogs.asp.net/scottgu/archive/2010/01/27/extensible-output-caching-with-asp-net-4-vs-2010-and-net-4-0-series.aspx

당신이 찾고있는 구현은 여기

** http://aspnet.4guysfromrolla.com/code/ExtensibleOutputCachingDemo.zip ** 찾을 수 있습니다 http://www.4guysfromrolla.com/articles/061610-1.aspx

에서 공급 이. web.config에서 모두 연결해야합니다.

+0

여기에 주요한 시간 제품이 있습니까? –

+0

나는 알고 있지 않습니다. 제공된 솔루션은 테스트를 통해 해결할 수 있지만 성능상의 문제는 아니며 때때로 데이터를 잃을 수도 있습니다. 나는 누군가가 memcached 제공자를 작성 했으므로 아마 당신이 성취하고자하는 것을 더 많이 할 것이라고 확신한다. –

+0

샘플을 확인했는데, 디스크가 가득 차면 가장 명백한 문제는 코드가 충돌한다는 것입니다. 어쨌든, asp.net 4.0은 여전히 ​​꽤 새롭고 개발중인 제품 일 수도 있습니다. –

1
// Based on code by 'Scott Mitchell' <[email protected]> 
// http://www.4guysfromrolla.com/articles/061610-1.aspx 

// Add the following to Web.config 
// Use the cacheFolder attribute to specify the disk location for the cache 
// 
// <system.web> 
// <caching> 
//  <outputCache enableOutputCache="true" defaultProvider="disk"> 
//   <providers> 
//    <add name="disk" type="DiskOutputCache.DiskOutputCacheProvider, DiskOutputCache" cacheFolder="~/App_Data/OutputCache" /> 
//   </providers> 
//  </outputCache> 
// </caching> 
// </system.web> 

using System; 
using System.Collections.Concurrent; 
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.IO; 
using System.Linq; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Text; 
using System.Web; 
using System.Web.Caching; 

namespace DiskOutputCache { 

    /// <summary> 
    /// An <see cref="OutputCacheProvider"/> that uses the file system for storage. 
    /// </summary> 
    public class DiskOutputCacheProvider : OutputCacheProvider { 

     readonly IDictionary<string, CacheItem> cacheItems = new ConcurrentDictionary<string, CacheItem>(); 
     string cacheFolder; 

     public override void Initialize(string name, NameValueCollection config) { 

     HttpServerUtility serverUtil = HttpContext.Current.Server; 

     const string cacheFolderKey = "cacheFolder"; 
     string cacheFolderValue = config[cacheFolderKey]; 
     string folder; 

     if (!String.IsNullOrEmpty(cacheFolderValue)) { 

      folder = serverUtil.MapPath(cacheFolderValue); 

      config.Remove(cacheFolderKey); 

     } else { 
      throw new ArgumentException(String.Format("The attribute '{0}' is missing in the configuration of the '{1}' provider.", cacheFolderKey, name)); 
     } 

     if (folder[folder.Length - 1] != Path.DirectorySeparatorChar) 
      folder += Path.DirectorySeparatorChar; 

     if (!Directory.Exists(folder)) 
      Directory.CreateDirectory(folder); 

     this.cacheFolder = folder; 

     base.Initialize(name, config); 
     } 

     public override object Add(string key, object entry, DateTime utcExpiry) { 

     // See if this key already exists in the cache. If so, we need to return it and NOT overwrite it! 
     object results = Get(key); 

     if (results != null) 
      return results; 

     // If the item is NOT in the cache, then save it! 
     Set(key, entry, utcExpiry); 

     return entry; 
     } 

     public override object Get(string key) { 

     CacheItem item; 

     if (!this.cacheItems.TryGetValue(key, out item)) 
      return null; 

     if (item.UtcExpiry < DateTime.UtcNow) { 

      // Item has expired 
      Remove(key, item); 

      return null; 
     } 

     return GetCacheData(item); 
     } 

     object GetCacheData(CacheItem item) { 

     string fileToRetrieve = GetFilePath(item); 

     BinaryFormatter formatter = new BinaryFormatter(); 
     Stream source = null; 

     try { 
      source = new FileStream(fileToRetrieve, FileMode.Open, FileAccess.Read, FileShare.Read); 

      return formatter.Deserialize(source); 

     } catch (IOException) { 

     } finally { 
      if (source != null) 
       source.Dispose(); 
     } 

     return null; 
     } 

     public override void Remove(string key) { 

     CacheItem item; 

     if (this.cacheItems.TryGetValue(key, out item)) 
      Remove(key, item); 
     } 

     void Remove(string key, CacheItem item) { 

     RemoveCacheData(item); 
     this.cacheItems.Remove(key); 
     } 

     void RemoveCacheData(CacheItem item) { 

     string fileToDelete = GetFilePath(item); 

     try { 
      File.Delete(fileToDelete); 
     } catch (IOException) { } 
     } 

     public override void Set(string key, object entry, DateTime utcExpiry) { 

     // Create a DiskOutputCacheItem object 
     CacheItem item = new CacheItem(key, utcExpiry); 

     WriteCacheData(item, entry); 

     // Add item to CacheItems, if needed, or update the existing key, if it already exists 
     this.cacheItems[key] = item; 
     } 

     void WriteCacheData(CacheItem item, object entry) { 

     string fileToWrite = GetFilePath(item); 

     BinaryFormatter formatter = new BinaryFormatter(); 
     Stream destination = null; 

     try { 
      destination = new FileStream(fileToWrite, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); 
      formatter.Serialize(destination, entry); 

     } catch (IOException) { 

     } finally { 
      if (destination != null) 
       destination.Dispose(); 
     } 
     } 

     string GetFilePath(CacheItem item) { 
     return this.cacheFolder + item.FileName; 
     } 

     class CacheItem { 

     static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); 

     public string FileName { get; private set; } 
     public DateTime UtcExpiry { get; private set; } 

     public CacheItem(string key, DateTime utcExpiry) { 

      this.FileName = GetSafeFileName(key); 
      this.UtcExpiry = utcExpiry; 
     } 

     string GetSafeFileName(string unsafeFileName) { 

      char[] invalid = unsafeFileName.ToCharArray() 
       .Where(c => invalidFileNameChars.Contains(c)) 
       .ToArray(); 

      if (invalid.Length > 0) { 

       var sb = new StringBuilder(unsafeFileName, unsafeFileName.Length); 

       for (int i = 0; i < invalid.Length; i++) 
        sb.Replace(invalid[i], '_'); 

       return sb.ToString(); 
      } 

      return unsafeFileName; 
     } 
     } 
    } 
} 
관련 문제