我对使用Polly项目中的缓存策略一无所知。 我已经按照示例设置了所有程序,并且似乎基本上可以正常工作。
我编写了一个单元测试,其中的值已成功检索,放入缓存并在以后的调用中从缓存中读取。 但是,当我在asp.net核心上下文中运行代码时,它无法按预期工作。包装的操作将执行并检索值。但是,从不执行放入缓存方法。 我尝试使用自己的IAsyncCacheProvider调试问题。而且它的PutAsync方法永远不会在asp.net上下文中调用。但是,在单元测试中运行时会调用它。
这是我的服务配置
services.AddSingleton<IAsyncCacheProvider, MemoryCacheProvider>();
services.AddSingleton<IPolicyRegistry<string>, PolicyRegistry>();
这里是引起问题的班级摘录。
public Bar(
IPolicyRegistry<string> policyRegistry,
IService service,
IAsyncCacheProvider cacheProvider)
{
this.policyRegistry = policyRegistry;
this.service = service;
this.cacheProvider = cacheProvider;
}
public Task<bool> Foo(Guid id)
{
var cachePolicy = this.GetPolicy();
return cachePolicy.ExecuteAsync(
_ => this.service.Foo(id),
new Context("policyKey" + id));
}
private CachePolicy<bool> GetPolicy()
{
if(!this.policyRegistry.TryGet(PolicyKey, out CachePolicy<bool> policy))
{
policy = Policy.CacheAsync<bool>(
this.cacheProvider.AsyncFor<bool>(),
TimeSpan.FromMinutes(5),
(c, s) => { },
(c, s) => { },
(c, s) => { },
(c, s, e) => { },
(c, s, e) => { });
this.policyRegistry.Add(PolicyKey, policy);
}
return policy;
}
任何想法,什么可能导致这种行为?当我放置断点时,它永远不会尝试将返回值添加到缓存中。也不例外。
答案 0 :(得分:1)
我想我在源代码中找到了答案。
在CacheEngine类中,有以下代码。
if (ttl.Timespan > TimeSpan.Zero && result != null && !result.Equals(default(TResult)))
{
try
{
await cacheProvider.PutAsync(cacheKey, result, ttl, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext);
onCachePut(context, cacheKey);
}
catch (Exception ex)
{
onCachePutError(context, cacheKey, ex);
}
}
因此,只要此服务的返回值bool碰巧为false,就不会将其放入缓存,因为这实际上是该类型的默认值。在单元测试中,我碰巧使用true作为返回值,因此缓存起作用了。