【发布时间】:2021-08-18 10:15:32
【问题描述】:
我为一个任务方法实现了 AOP。在AOP中,我实现了缓存的逻辑。在方法执行之前,我进入AOP的逻辑判断是否有缓存。如果缓存命中,我直接返回。如果缓存没有命中,我执行方法,然后将方法的执行结果插入缓存。但是,如果命中缓存,则报如下错误
InnerException
{"Unable to cast object of type 'System.Threading.Tasks.Task`1[System.Object]' to type
'System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[cooperation_error_typeModel]]'."}
System.Exception {System.InvalidCastException}
/// <summary>
///
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class CacheAttribute: Attribute
{
/// <summary>
///
/// </summary>
public int ExpirationSeconds { get; }
/// <summary>
///
/// </summary>
/// <param name="expirationSeconds"></param>
public CacheAttribute(int expirationSeconds)
{
this.ExpirationSeconds = expirationSeconds;
}
}
[Intercept(typeof(CacheInterceptor))]
[Repository]
public class CoopErrorTypeRepository : ICoopErrorTypeRepository
{
/// <summary>
///
/// </summary>
/// <param name="coopId"></param>
/// <returns></returns>
[Cache(300)]
public async Task<IEnumerable<cooperation_error_typeModel>> GetCoopErrorTypeList(string coopId)
{
return new cooperation_error_typeModel();
}
}
public class CacheInterceptor : IInterceptor
{
/// <summary>
/// Intercept
/// </summary>
/// <param name="invocation"></param>
public void Intercept(IInvocation invocation)
{
var method = invocation.MethodInvocationTarget ?? invocation.Method;
var cacheAttribute = this.GetQCachingAttributeInfo(method);
if (cacheAttribute != null)
{
ProceedCaching(invocation, cacheAttribute, method);
}
else
{
invocation.Proceed();
}
}
private CacheAttribute GetQCachingAttributeInfo(MethodInfo method)
{
return method.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(CacheAttribute)) as CacheAttribute;
}
private void ProceedCaching(IInvocation invocation, CacheAttribute attribute, MethodInfo method)
{
var cacheKey = GetCacheKey(invocation.Arguments);
var client = RedisHelper.redisClientFactory.GetClient("CooperationDataCache");
var cacheValue = client.String.Get(cacheKey);
if (!string.IsNullOrWhiteSpace(cacheValue))
{
if (method.ReturnType.BaseType == (typeof(Task)))
{
Type[] genericTypeArguments = method.ReturnType.GenericTypeArguments;
if (genericTypeArguments != null && genericTypeArguments.Length > 0)
{
invocation.ReturnValue = Task.FromResult(JsonConvert.DeserializeObject(cacheValue, genericTypeArguments[0]));
}
}
}
else
{
invocation.Proceed();
if (method.ReturnType.BaseType == (typeof(Task)))
{
//if (!(method.Invoke(invocation.InvocationTarget, invocation.Arguments) is Task task)) return;
var task = (Task)invocation.ReturnValue;
task.ContinueWith(m =>
{
if (task.Status != TaskStatus.RanToCompletion) return;
var result = ConvertHelperExtend.PackJson(((dynamic)task).Result);
client.String.Set(cacheKey, result);
client.Key.Expire(cacheKey, attribute.ExpirationSeconds);
});
}
else
{
client.String.Set(cacheKey, ConvertHelperExtend.PackJson(invocation.ReturnValue));
client.Key.Expire(cacheKey, attribute.ExpirationSeconds);
}
}
}
/// <summary>
/// get cache key
/// </summary>
/// <param name="invocation"></param>
/// <returns></returns>
private string GetCacheKey(object[] arguments)
{
if (arguments == null || arguments.Length < 1) return string.Empty;
foreach (var argument in arguments)
{
if (argument is IGetCacheKey cacheKeyObj)
return cacheKeyObj.CacheKey;
}
return string.Empty;
}
}
/// <summary>
/// cache key
/// </summary>
public interface IGetCacheKey
{
/// <summary>
/// cache key
/// </summary>
string CacheKey { get; }
}
【问题讨论】:
-
您可能无法在此处获得答案。您发布的异常并没有告诉任何人它在代码中发生的位置,也没有人会设置一个完整的重现解决方案来为您调试它。自己调试更多并描述您发现的内容可能会更好。