2009-06-24 51 views
29

Bối cảnh: .Net 3.5, C#
Tôi muốn có cơ chế lưu trong bộ nhớ cache trong ứng dụng Bảng điều khiển của mình.
Thay vì phát minh lại bánh xe, tôi muốn sử dụng System.Web.Caching.Cache (và đó là quyết định cuối cùng, tôi không thể sử dụng khung bộ nhớ đệm khác, không hỏi tại sao).
Tuy nhiên, có vẻ như System.Web.Caching.Cache được cho là chỉ chạy trong ngữ cảnh HTTP hợp lệ. My đoạn rất đơn giản như sau:Tôi có thể sử dụng System.Web.Caching.Cache trong ứng dụng Console như thế nào?

using System; 
using System.Web.Caching; 
using System.Web; 

Cache c = new Cache(); 

try 
{ 
    c.Insert("a", 123); 
} 
catch (Exception ex) 
{ 
    Console.WriteLine("cannot insert to cache, exception:"); 
    Console.WriteLine(ex); 
} 

và kết quả là:

 
cannot insert to cache, exception: 
System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.Web.Caching.Cache.Insert(String key, Object value) 
    at MyClass.RunSnippet() 

Vì vậy, rõ ràng, tôi đang làm một cái gì đó sai ở đây. Ý tưởng nào?


Cập nhật: +1 với hầu hết các câu trả lời, nhận được bộ nhớ cache thông qua phương pháp tĩnh là sử dụng chính xác, cụ thể là HttpRuntime.CacheHttpContext.Current.Cache. Cảm ơn tất cả!

Trả lời

56

Tài liệu dành cho trình tạo bộ nhớ cache cho biết rằng nó chỉ dành cho mục đích sử dụng nội bộ. Để có được đối tượng Cache của bạn, hãy gọi HttpRuntime.Cache thay vì tạo một cá thể thông qua hàm tạo.

9

Chỉ cần sử dụng Caching Application Block nếu bạn không muốn phát minh lại bánh xe. Nếu bạn vẫn muốn sử dụng bộ nhớ cache ASP.NET- see here. Tôi khá chắc chắn điều này chỉ hoạt động với NET 2.0 và ở trên mặc dù. Nó chỉ đơn giản là không thể sử dụng bộ nhớ cache bên ngoài của ASP.NET trong .NET 1.

MSDN có một cảnh báo lớn thoải mái trên trang cho tài liệu bộ nhớ cache quá:

Lớp cache không phải là dành cho sử dụng bên ngoài các ứng dụng ASP.NET. Nó được thiết kế và thử nghiệm để sử dụng trong ASP.NET để cung cấp bộ nhớ đệm cho các ứng dụng Web . Trong các loại ứng dụng khác, chẳng hạn như giao diện điều khiển ứng dụng hoặc Windows Forms ứng dụng, bộ nhớ đệm ASP.NET có thể không hoạt động chính xác.

Vì một giải pháp rất nhẹ, nơi bạn không phải lo lắng về việc hết hạn, thì đối tượng từ điển có thể đủ.

+0

"nhìn thấy ở đây" liên kết bị phá vỡ –

+0

@ Ron- đó là một lỗi Stackoverflow. Đây là một TinyUrl cho cùng một liên kết- http://tinyurl.com/ms35eu – RichardOD

1

Hãy thử

public class AspnetDataCache : IDataCache 
{ 
    private readonly Cache _cache; 

    public AspnetDataCache(Cache cache) 
    { 
     _cache = cache; 
    } 

    public AspnetDataCache() 
     : this(HttpRuntime.Cache) 
    { 

    } 
    public void Put(string key, object obj, TimeSpan expireNext) 
    { 
     if (key == null || obj == null) 
      return; 
     _cache.Insert(key, obj, null, DateTime.Now.Add(expireNext), TimeSpan.Zero); 
    } 

    public object Get(string key) 
    { 
     return _cache.Get(key); 
    } 

1

Lớp System.Web.Caching.Cache dựa vào việc có thành viên "_cacheInternal" được thiết lập bởi các đối tượng httpRuntime.

Để sử dụng lớp System.Web.Caching, bạn phải tạo đối tượng HttpRuntime và thiết lập thuộc tính HttpRuntime.Cache. Bạn đã có hiệu quả để mô phỏng IIS.

Bạn nên sử dụng bộ nhớ đệm khung khác như:

+1

"Cách duy nhất để thiết lập đó là thông qua các phương thức nội bộ" - không đúng, _cacheInternal được thiết lập bởi trình truy cập thuộc tính tĩnh HttpRuntime.Cache. Tuy nhiên tôi sẽ được quan tâm đến thông tin thêm về lý do tại sao MSDN khuyến cáo ASP.NET Cache không nên được sử dụng trong các ứng dụng không web. Tôi có mã sử dụng nó (mà ngày trước khi sự tồn tại của cảnh báo này), và nó * có vẻ * để làm việc OK. – Joe

+0

Cảm ơn @Joe - chỉnh sửa câu trả lời của tôi – d4nt

4

tôi đã kết thúc trên trang này tự hỏi điều tương tự. Dưới đây là những gì tôi đang làm (mà tôi không thích nhưng dường như chỉ hoạt động tốt):

HttpContext context = HttpContext.Current; 
if (context == null) 
{ 
    HttpRequest request = new HttpRequest(string.Empty, "http://tempuri.org", string.Empty); 
    HttpResponse response = new HttpResponse(new StreamWriter(new MemoryStream())); 
    context = new HttpContext(request, response); 
    HttpContext.Current = context; 
} 
this.cache = context.Cache; 
+1

Điều này rất bẩn nhưng nó thực sự có ích khi tôi có một mẫu thử nghiệm tích hợp với một dll bên ngoài dựa trên HttpContext.Current.Cache và tôi chỉ cần nó hoạt động. Tôi tìm thấy một phiên bản ngắn hơn ở đây: http://caioproiete.net/en/fake-mock-httpcontext-without-any-special-mocking-framework/ – bygrace

28

Trong khi OP được chỉ định v3.5, câu hỏi được hỏi trước khi v4 được phát hành. Để giúp bất kỳ ai tìm thấy câu hỏi này, có thể sống với sự phụ thuộc v4, nhóm khung đã tạo bộ nhớ cache đa mục đích mới cho loại kịch bản này. Đó là trong không gian tên System.Runtime.Caching: http://msdn.microsoft.com/en-us/library/dd997357%28v=VS.100%29.aspx

Tham chiếu tĩnh để thể hiện bộ nhớ cache mặc định là: MemoryCache.Default

+0

Cảm ơn bạn đã tip! –

+3

Rất hữu ích! Tôi đang chuyển đổi cuộc gọi trong webapp của tôi để sử dụng phương pháp mới này thay thế. Bây giờ những phương thức này có thể được kiểm tra đơn vị mà không cần HttpContext.Cache được định nghĩa. :) – ClearCloud8

Các vấn đề liên quan