是否有可能缓存使用 WCF 从 OData 服务检索的集合。
情况如下:
我使用 odata 服务的元数据通过 Visual Studio 2015 生成了一个 WCF 服务客户端。 VS生成了一个继承自System.Data.Services.Client.DataServiceContext
的类.此类具有 System.Data.Services.Client.DataServiceQuery<T>
类型的一些属性.其中一些属性的数据很少更改。由于性能原因,我希望 WCF 客户端仅在第一次而不是每次我在代码中使用它时加载这些属性。
是否有内置的可能性来缓存这些属性的数据?或者我可以告诉服务客户端不要每次都重新加载特定属性。
假设服务客户端类是ODataClient
它的属性之一是“面积”,现在我通过以下方式获取值:
var client = new ODataClient("url_to_the_service");
client.IgnoreMissingProperties = true;
var propertyInfo = client.GetType().GetProperty("Area");
var area = propertyInfo.GetValue(client) as IEnumerable<object>;
我之所以以如此复杂的方式这样做,是因为客户端应该非常通用:可以在配置文件中配置要处理的属性。
* 编辑 *
我已经尝试在 System.Data.Services.Client.DataServiceContext
中查找属性类或 System.Data.Services.Client.DataServiceQuery<T>
缓存类。但我找不到任何内容。
最佳答案
据我所知,客户端没有“开箱即用”的缓存概念。有一些选项可以在服务器上缓存请求的输出,这也是您可能需要考虑的。谷歌搜索“WCF 缓存”将为您提供大量相关信息。
关于客户端缓存...@Evk 是正确的,它非常简单。这是使用 MemoryCache 的示例.
using System;
using System.Runtime.Caching;
namespace Services.Util
{
public class CacheWrapper : ICacheWrapper
{
ObjectCache _cache = MemoryCache.Default;
public void ClearCache()
{
MemoryCache.Default.Dispose();
_cache = MemoryCache.Default;
}
public T GetFromCache<T>(string key, Func<T> missedCacheCall)
{
return GetFromCache<T>(key, missedCacheCall, TimeSpan.FromMinutes(5));
}
public T GetFromCache<T>(string key, Func<T> missedCacheCall, TimeSpan timeToLive)
{
var result = _cache.Get(key);
if (result == null)
{
result = missedCacheCall();
if (result != null)
{
_cache.Set(key, result, new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.Add(timeToLive) });
}
}
return (T)result;
}
public void InvalidateCache(string key)
{
_cache.Remove(key);
}
}
}
这是一个使用缓存的代码示例...
private class DataAccessTestStub
{
public const string DateTimeTicksCacheKey = "GetDateTimeTicks";
ICacheWrapper _cache;
public DataAccessTestStub(ICacheWrapper cache)
{
_cache = cache;
}
public string GetDateTimeTicks()
{
return _cache.GetFromCache(DateTimeTicksCacheKey, () =>
{
var result = DateTime.Now.Ticks.ToString();
Thread.Sleep(100); // Create some delay
return result;
});
}
public string GetDateTimeTicks(TimeSpan timeToLive)
{
return _cache.GetFromCache(DateTimeTicksCacheKey, () =>
{
var result = DateTime.Now.Ticks.ToString();
Thread.Sleep(500); // Create some delay
return result;
}, timeToLive);
}
public void ClearDateTimeTicks()
{
_cache.InvalidateCache(DateTimeTicksCacheKey);
}
public void ClearCache()
{
_cache.ClearCache();
}
}
如果你喜欢,还有一些测试......
[TestClass]
public class CacheWrapperTest
{
private DataAccessTestStub _dataAccessTestClass;
[TestInitialize]
public void Init()
{
_dataAccessTestClass = new DataAccessTestStub(new CacheWrapper());
}
[TestMethod]
public void GetFromCache_ShouldExecuteCacheMissCall()
{
var original = _dataAccessTestClass.GetDateTimeTicks();
Assert.IsNotNull(original);
}
[TestMethod]
public void GetFromCache_ShouldReturnCachedVersion()
{
var copy1 = _dataAccessTestClass.GetDateTimeTicks();
var copy2 = _dataAccessTestClass.GetDateTimeTicks();
Assert.AreEqual(copy1, copy2);
}
[TestMethod]
public void GetFromCache_ShouldRespectTimeToLive()
{
_dataAccessTestClass.ClearDateTimeTicks();
var copy1 = _dataAccessTestClass.GetDateTimeTicks(TimeSpan.FromSeconds(2));
var copy2 = _dataAccessTestClass.GetDateTimeTicks();
Assert.AreEqual(copy1, copy2);
Thread.Sleep(3000);
var copy3 = _dataAccessTestClass.GetDateTimeTicks();
Assert.AreNotEqual(copy1, copy3);
}
[TestMethod]
public void InvalidateCache_ShouldClearCachedVersion()
{
var original = _dataAccessTestClass.GetDateTimeTicks();
_dataAccessTestClass.ClearDateTimeTicks();
var updatedVersion = _dataAccessTestClass.GetDateTimeTicks();
Assert.AreNotEqual(original, updatedVersion);
}
}
关于c# - WCF:如何在客户端缓存来自 OData 的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36063714/