2009-05-28 27 views
41

Tôi đang xây dựng một dịch vụ WCF. Tôi cần phải lưu trữ dữ liệu tham khảo trong bộ nhớ cache mà tôi sẽ tra cứu mỗi khi tôi nhận được đầu vào từ phương pháp ... Cách thích hợp để làm điều này là gì? Tôi cũng muốn xác định chính sách hết hạn cho bộ nhớ cache sẽ làm mất hiệu lực sau một khoảng thời gian nhất định.Caching trong WCF?

+3

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/8ee823e4-b592-475b-b916-883aeb9fed5b –

Trả lời

1

Bạn có thể xem Velocity. Đây là phân phối của Microsoft trong bộ nhớ caching framework. Nhưng điều này có thể hơi quá beta ...

0

Bạn có thể sử dụng System.Web.Cache (ngay cả khi bạn không ở trong ngữ cảnh web), và đó là những gì tôi muốn làm. Về cơ bản nó là một bảng băm lớn trong bộ nhớ với một số nội dung tuyệt vời cho nội dung hết hạn.

+2

thực hiện việc này hoặc để lại nó ...nhưng đây là trực tiếp từ msdn: Lớp Cache không nhằm mục đích sử dụng 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ư ứng dụng giao diện điều khiển hoặc ứng dụng Windows Forms, bộ nhớ đệm ASP.NET có thể không hoạt động chính xác. –

0

Có nhiều cách bạn có thể thực hiện việc này. Một cách khá đơn giản là tự mình lưu trữ đối tượng System.Web.Cache và sử dụng nó để lưu trữ dữ liệu tham chiếu. Có một ví dụ điển hình về điều đó tại đây: http://kjellsj.blogspot.com/2007/11/wcf-caching-claims-using.html

+2

Như Simon lưu ý, MS nói "Lớp Cache không có ý định sử dụng 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ư bàn điều khiển ứng dụng hoặc ứng dụng Windows Forms, bộ nhớ đệm ASP.NET có thể không hoạt động chính xác. " –

0

Thay vì hết hạn dữ liệu bộ nhớ cache tất cả vì vậy thường xuyên, bạn có thể thực sự chỉ cần đảm bảo để làm mất hiệu lực bộ nhớ cache bất cứ khi nào dữ liệu cơ bản bạn có bộ nhớ đệm thay đổi.

Xem ví dụ này từ thông tin Q http://www.infoq.com/news/2011/04/Attribute-Caching

[Cache.Cacheable("UserTransactionCache")] 
public DataTable GetAllTransactionsForUser(int userId) 
{ 
    return new DataProvider().GetAllTransactionsForUser(userId); 
} 

[Cache.TriggerInvalidation("UserTransactionCache")] 
public void DeleteAllTransactionsForUser(int userId) 
{ 
... 
} 
29

Nếu bạn đang sử dụng .NET 4, cách khuyến cáo là sử dụng MemoryCache

+6

Hãy xem bài viết trên blog này để có ví dụ về cách sử dụng nó: http://pieterderycke.wordpress.com/2012/04/09/caching-in-wcf-services-part-1/ – MuSTaNG

+0

Giải pháp tuyệt vời, không xml, không có cấu hình web. – Akli

+2

Chỉ cần đảm bảo vứt bỏ bộ nhớ cache của bạn hoặc bạn sẽ bị rò rỉ bộ nhớ tốt. Tôi biết ... điều này khiến tôi mất nhiều thời gian trong cuộc đời. –

27

Bất kỳ giải pháp bộ nhớ đệm nên giải quyết hai vấn đề cơ bản

1) Lưu trữ các mục trong bộ nhớ cache và truy xuất

2) Vô hiệu hóa bộ nhớ cache

Vì Http caching là một bộ nhớ nổi tiếng, tôi sẽ không giải thích chi tiết. Bạn có thể sử dụng thuộc tính tương thích asp một mình với một số cấu hình web, nơi bạn sẽ nhận được bộ nhớ đệm bằng sự quyến rũ.

[AspNetCacheProfile("MyProfile")] 
     public Customer GetName(string id) 
     { 
      // ... 
     } 

Và cấu hình web cũng giống như

<system.serviceModel> 
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />  
</system.serviceModel> 
<system.web> 
    <caching> 
     <outputCacheSettings> 
     <outputCacheProfiles> 
      <add name=" MyProfile" duration="600" varyByParam="none" sqlDependency="MyTestDatabase:MyTable"/> 
     </outputCacheProfiles> 
     </outputCacheSettings> 
    </caching> 
</system.web> 

Nhưng điều này là không thích hợp cho hầu hết các tình huống đặc biệt là khi bạn có đối tượng phức tạp lớn để bộ nhớ cache. Ví dụ tôi đã có một tình huống mà tôi muốn cache một hệ thống tạo ra hình ảnh (đầu ra của hợp đồng hoạt động là một hệ thống tạo ra hình ảnh mà phụ thuộc vào đầu vào). Trong trường hợp này, bạn phải triển khai bộ nhớ cache của riêng bạn. Tôi đã sử dụng các khối bộ nhớ đệm thư viện doanh nghiệp của Microsoft giải quyết tất cả các yêu cầu bộ nhớ đệm của tôi. Tuy nhiên, bạn vẫn cần phải làm hệ thống ống nước để tích hợp khối bộ nhớ đệm thư viện doanh nghiệp của Microsoft với dịch vụ WCF của bạn. Trước tiên, bạn phải chặn kênh liên lạc WCF để triển khai bộ nhớ cache. Một cuộc thảo luận chi tiết về cách đánh chặn kênh truyền thông WCF có thể được tìm thấy tại http://msdn.microsoft.com/en-us/magazine/cc163302.aspx. Đây là cách bạn làm hệ thống ống nước cho WCF bộ nhớ đệm

Basic Plumbing Architecture

Bước 0 Hãy nói rằng bạn có một hợp đồng hoạt động như sau và bạn muốn bộ nhớ cache sự trở lại mục bằng phương pháp đó.

[OperationContract] 
MyCompositeClass Rotate(int angle) 

Bước 1 Trước tiên, bạn phải đăng ký cacher tùy chỉnh của bạn trong các đường ống WCF. Để làm điều đó tôi sẽ sử dụng một thuộc tính để tôi có thể trang trí độc đáo cuộc gọi WCF của tôi theo các nguyên tắc lập trình hướng khía cạnh.

using System; 
using System.ServiceModel.Description; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Dispatcher; 
using System.Reflection; 

    [AttributeUsage(AttributeTargets.Method)] 
    public class MyCacheRegister : Attribute, IOperationBehavior 
    { 
     ConstructorInfo _chacherImplementation; 
     public ImageCache(Type provider) 
     { 
      if (provider == null) 
      { 
       throw new ArgumentNullException("Provider can't be null"); 
      } 
      else if (provider.IsAssignableFrom(typeof(IOperationInvoker))) 
      { 
       throw new ArgumentException("The type " + provider.AssemblyQualifiedName + " does not implements the interface " + typeof(IOperationInvoker).AssemblyQualifiedName); 
      } 
      else 
      { 
       try 
       { 
        Type[] constructorSignatureTypes = new Type[1]; 
        constructorSignatureTypes[0] = typeof(IOperationInvoker); 
        _chacherImplementation = provider.GetConstructor(constructorSignatureTypes); 

       } 
       catch 
       { 
        throw new ArgumentException("There is no constructor in " + provider.AssemblyQualifiedName + " that accept " + typeof(IOperationInvoker).AssemblyQualifiedName + " as a parameter"); 
       } 

      } 


     } 

     public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) 
     { 
      return; 
     } 

     public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) 
     { 
      return; 
     } 

     /// <summary> 
     /// Decorate the method call with the cacher 
     /// </summary> 
     public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) 
     { 
      //decorator pattern, decorate with a cacher 
      object[] constructorParam = new object[1]; 
      constructorParam[0] = dispatchOperation.Invoker; 
      dispatchOperation.Invoker = (IOperationInvoker)_chacherImplementation.Invoke(constructorParam); 
     } 

     public void Validate(OperationDescription operationDescription) 
     { 
      return; 
     } 
    } 

Bước 2

Sau đó, bạn phải thực hiện các điểm mà đối tượng bộ nhớ cache sẽ được lấy ra.

using System; 
using System.ServiceModel.Dispatcher; 
using Microsoft.Practices.EnterpriseLibrary.Caching; 
using Microsoft.Practices.EnterpriseLibrary.Common; 
using System.IO; 

    class RotateCacher : IOperationInvoker 
    { 

     private IOperationInvoker _innerOperationInvoker; 
     public RotateImageCacher(IOperationInvoker innerInvoker) 
     { 
      _innerOperationInvoker = innerInvoker; 
     } 
     public object[] AllocateInputs() 
     { 
      Object[] result = _innerOperationInvoker.AllocateInputs(); 
      return result; 
     } 

     public object Invoke(object instance, object[] inputs, out object[] outputs) 
     { 
      object result=null; 

///TODO: You will have more object in the input if you have more ///parameters in your method 

      string angle = inputs[1].ToString(); 

      ///TODO: create a unique key from the inputs 
      string key = angle; 

      string provider = System.Configuration.ConfigurationManager.AppSettings["CacheProviderName"]; 
      ///Important Provider will be DiskCache or MemoryCache for the moment 
provider =”DiskCache”; 
///TODO: call enterprise library cache manager, You can have your own 
/// custom cache like Hashtable 

    ICacheManager manager = CacheFactory.GetCacheManager(provider); 

      if (manager.Contains(key)) 
      { 

       result =(MyCompositeClass) manager[key]; 

      } 
      else 
      { 
       result =(MyCompositeClass) _innerOperationInvoker.Invoke(instance, inputs, out outputs); 
       manager.Add(key, result); 
      } 
      return result; 
     } 

     public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) 
     { 
      IAsyncResult result = _innerOperationInvoker.InvokeBegin(instance, inputs, callback, state); 
      return result; 
     } 

     public object InvokeEnd(object instance, out object[] outputs, IAsyncResult asyncResult) 
     { 
      object result = _innerOperationInvoker.InvokeEnd(instance, out outputs, asyncResult); 
      return result; 
     } 

     public bool IsSynchronous 
     { 
      get { return _innerOperationInvoker.IsSynchronous; } 
     } 
    } 

Bước 3

Cuối cùng thêm thuộc tính của bạn trên cuộc gọi dịch vụ của bạn

[OperationContract] 
[MyCacheRegister(typeof(RotateCacher)] 
MyCompositeClass Rotate(int angle) 

Cấu hình của thư viện doanh nghiệp bộ nhớ đệm khối nằm ngoài phạm vi của câu trả lời này. Bạn có thể sử dụng liên kết sau để tìm hiểu nó. Điều tốt về thư viện doanh nghiệp là bạn đã sẵn sàng thực hiện các cách để mở rộng chính sách bộ nhớ đệm của mình. Nó đã được xây dựng theo cách cho bộ nhớ cache hết hạn và lưu trữ. Bạn cũng có thể viết các chính sách lưu trữ và hết hạn bộ nhớ cache của chính mình. http://www.codeproject.com/KB/web-cache/CachingApplicationBlock.aspx

Một điều cuối cùng, để bạn có được bộ nhớ đệm trong thư viện doanh nghiệp của mình, bạn cần thêm chi tiết cấu hình sau. Bạn cũng cần phải thêm dlls có liên quan để tham khảo dự án của bạn.

<configSections> 
    <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> 
    </configSections> 


    <cachingConfiguration defaultCacheManager="Cache Manager"> 
    <cacheManagers> 
     <add name="MemoryCache" type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
     expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" 
     numberToRemoveWhenScavenging="10" backingStoreName="NullBackingStore" /> 
     <add name="DiskCache" type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
     expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" 
     numberToRemoveWhenScavenging="10" backingStoreName="IsolatedStorageCacheStore" /> 
    </cacheManagers> 
    <backingStores> 
     <add type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
     name="NullBackingStore" /> 
     <add name="IsolatedStorageCacheStore" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.IsolatedStorageBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
     encryptionProviderName="" partitionName="MyCachePartition" /> 
    </backingStores> 
    </cachingConfiguration> 
+0

Tôi hy vọng bạn không có kế hoạch sao chép câu trả lời này cho mọi câu hỏi bộ nhớ đệm cũ mà bạn tìm thấy trên trang web. Thay vào đó, hãy cân nhắc gắn cờ một số câu hỏi dưới dạng bản sao. –

+0

cũng không biết rằng có một lựa chọn như thế. làm thế nào để làm điều đó? –

+0

Có một liên kết cờ bên dưới mỗi câu hỏi. –

1

Nếu bạn đang đi để được nhân rộng ra nhiều hơn một máy chủ trong một tải cân bằng, hệ thống không quốc tịch, bạn sẽ muốn design for use of a distributed cache. Những điều chính cần làm ở đây là:

  1. Sử dụng cả bộ nhớ cache cục bộ và phân phối. Chỉ đặt phiên hoặc ngắn công cụ sống trong bộ nhớ cache được phân phối, bộ nhớ cache nội dung khác cục bộ.

  2. Đặt thời gian chờ phù hợp cho các mục. Điều này sẽ khác nhau tùy thuộc vào loại thông tin và mức độ gần với nguồn thông tin cần thiết.

  3. Xóa nội dung khỏi bộ nhớ cache khi bạn biết nó sẽ không phổ biến (như cập nhật, xóa, v.v ...).

  4. Cẩn trọng thiết kế các khóa bộ nhớ cache duy nhất. Tạo mô hình của loại thông tin bạn lập kế hoạch để lưu vào bộ nhớ cache và sử dụng thông tin đó làm mẫu cho các khóa xây dựng .