C# 有没有办法重构两个方法,一个调用等待的方法,另一个调用普通方法?
我正在为一个网站构建一个缓存服务,我想提供一个公共界面,它可以采用C# 有没有办法重构两个方法,一个调用等待的方法,另一个调用普通方法?,c#,asp.net-mvc-4,functional-programming,async-await,func,C#,Asp.net Mvc 4,Functional Programming,Async Await,Func,我正在为一个网站构建一个缓存服务,我想提供一个公共界面,它可以采用Func或Func方法a,该方法可以由服务调用,用于缓存未命中 在处理这两种委托类型时,我会重复代码。有没有办法巩固?我特别担心“Func”方法不是线程安全的,不适合包装在“Task.Run”中 这是我的密码: 公共接口ICacheServiceEngine { 任务TryGetValueAsync(字符串键); 任务 TryGetValueAsync(TKey-key,Func-keyFunc); 任务GetValueAsyn
Func
或Func
方法a,该方法可以由服务调用,用于缓存未命中
在处理这两种委托类型时,我会重复代码。有没有办法巩固?我特别担心“Func”方法不是线程安全的,不适合包装在“Task.Run”中
这是我的密码:
公共接口ICacheServiceEngine
{
任务TryGetValueAsync(字符串键);
任务
TryGetValueAsync(TKey-key,Func-keyFunc);
任务GetValueAsync(字符串键,
Func valueSourceFunc);
任务GetValueAsync(TKey,
Func-keyFunc,Func-valueSourceFunc);
任务GetValueAsync(字符串键,
Func valueSourceFuncAsync);
任务GetValueAsync(TKey,
Func-keyFunc,Func-valueSourceFuncAsync);
}
公共接口ICacheServiceDataAccessor
{
任务TryGetAsync(字符串键);
任务PutAsync(字符串键,TValue结果);
}
公共类CacheServiceEngine:ICacheServiceEngine
{
专用ICacheServiceDataAccessor cacheDataAccessor;
公共CacheServiceEngine(ICacheServiceDataAccessor cacheDataAccessor)
{
//加护
this.cacheDataAccessor=cacheDataAccessor;
}
公共异步任务TryGetValueAsync(字符串键)
{
return wait this.cacheDataAccessor.TryGetAsync(key);
}
公共异步任务TryGetValueAsync(TKey,
Func键(Func)
{
字符串keyString=keyFunc(键);
return wait this.cacheDataAccessor.TryGetAsync(键串);
}
公共异步任务GetValueAsync(字符串键,
Func valueSourceFunc)
{
return等待此操作。InnerGetValueAsync(键,()=>valueSourceFunc(键));
}
公共异步任务GetValueAsync(TKey,
Func keyFunc,Func valueSourceFunc)
{
字符串keyString=keyFunc(键);
return等待此操作。InnerGetValueAsync(键字符串,()=>valueSourceFunc(键));
}
公共异步任务GetValueAsync(字符串键,
Func valueSourceFuncAsync)
{
return等待这个。InnerGetValueAsync(key,()=>valueSourceFuncAsync(key));
}
公共异步任务GetValueAsync(TKey,
Func keyFunc,Func valueSourceFuncAsync)
{
字符串keyString=keyFunc(键);
return等待此消息。InnerGetValueAsync(keyString,
()=>valueSourceFuncAsync(键));
}
//这两个私有方法彼此非常接近
//如果我假设‘valueSourceFunc’,我能找出相似之处吗
//线程不是安全的吗?
专用异步任务InnerGetValueAsync(字符串键,
Func valueSourceFunc)
{
t价值;
CacheResult CacheResult=
等待这个.cacheDataAccessor.TryGetAsync(键);
if(cacheResult.InCache)
{
value=cacheResult.value;
}
其他的
{
//此呼叫正常(同步)
value=valueSourceFunc();
等待这个.cacheDataAccessor.PutAsync(键,值);
}
返回值;
}
专用异步任务InnerGetValueAsync(字符串键,
Func valueSourceFuncAsync)
{
t价值;
CacheResult CacheResult=
等待这个.cacheDataAccessor.TryGetAsync(键);
if(cacheResult.InCache)
{
value=cacheResult.value;
}
其他的
{
//这个电话必须等待
value=wait valueSourceFuncAsync();
等待这个.cacheDataAccessor.PutAsync(键,值);
}
返回值;
}
}
首先,您应该重新考虑您的ICacheServiceDataAccessor
。当某个键不在缓存中时,完全可能会不必要地计算值。我建议这样做:
public interface ICacheServiceDataAccessor
{
Task<CacheResult<TValue>> TryGetAsync<TValue>(string key);
Task<CacheResult<TValue>> GetOrPutAsync<TValue>(string key, Func<Task<TValue>> result);
}
作为最后的设计说明,我认为只有这些最通用的是“代码> iCaseServEngEngEng/<代码>的实际成员。由于其他方法实际上只是该方法的重载(并且无论派生类如何,它们都将始终具有相同的实现),因此可以在
ICacheServiceEngine
上定义为扩展方法。首先,您应该重新考虑ICacheServiceDataAccessor
。当某个键不在缓存中时,完全可能会不必要地计算值。我建议这样做:
public interface ICacheServiceDataAccessor
{
Task<CacheResult<TValue>> TryGetAsync<TValue>(string key);
Task<CacheResult<TValue>> GetOrPutAsync<TValue>(string key, Func<Task<TValue>> result);
}
作为最后的设计说明,我认为只有这些最通用的是“代码> iCaseServEngEngEng/<代码>的实际成员。由于其他方法实际上只是该方法的重载(并且无论派生类是什么,它们都将具有相同的实现),因此它们可以定义为
icacheserviceenge
上的扩展方法