gpt4 book ai didi

c# - WCF:如何在客户端缓存来自 OData 的集合

转载 作者:太空狗 更新时间:2023-10-30 01:16:11 25 4
gpt4 key购买 nike

是否有可能缓存使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com