C# 异步函数陷入死锁?

C# 异步函数陷入死锁?,c#,async-await,func,stackexchange.redis,C#,Async Await,Func,Stackexchange.redis,目标: 我正在使用redis进行缓存,并尝试获取缓存值(如果不可用),从repo获取并设置缓存值 问题: 客户端js一直在等待,似乎处于某种类型的死锁中 导致问题的代码 return await _cacheStore.GetAsync("CacheKey", new TimeSpan(24, 0, 0), async () => await _repo.GetAllAsync()

目标:

我正在使用redis进行缓存,并尝试获取缓存值(如果不可用),从repo获取并设置缓存值

问题:

客户端js一直在等待,似乎处于某种类型的死锁中

导致问题的代码

   return await _cacheStore.GetAsync("CacheKey", new TimeSpan(24, 0, 0),
                 async () =>
                  await _repo.GetAllAsync()
                  );
public static async Task < T > GetAsync < T > (this IRedisCacheStore source, string key, TimeSpan time, Func < Task < T >> fetch) where T: class {
 if (source.Exists(key)) {
  return await source.GetAsync < T > (key);
 } else {
  var result = fetch();

  if (result != null) {
   source.Set(key, result, time);
  }

  return await result;
 }
}

public async Task < List < ObjectType >> GetAllAsync() {
 var result = await _procExecutor.ExecuteProcAsync < ObjectType > ("Sproc", null);

 return (result ? ? new List < ObjectType > ()).ToList();
}

public async Task < IEnumerable < TResult >> ExecuteProcAsync < TResult > (string sproc, object param) {
  using(var conn = _connection.GetConnection()) {
   return await conn.QueryAsync < TResult > (sproc, param, commandType: CommandType.StoredProcedure);
  }
代码可以工作,但有点多余,因为我在很多地方一直使用这种模式。

    var data = await _cacheStore.GetAsync<List<objectType>>("cacheKey");
    if (data == null)
    {
        data = await _repo.GetAllAsync();
        _cacheStore.SetAsync<List<objectType>>("cacheKey", data, new TimeSpan(24, 0, 0));
    }
    return data;
var data=await\u cacheStore.GetAsync(“cacheKey”);
如果(数据==null)
{
数据=等待_repo.GetAllAsync();
_SetAsync(“cacheKey”,数据,新的时间跨度(24,0,0));
}
返回数据;
//下面可能有问题的函数将异步方法传递为Func????? 上述代码调用的函数

   return await _cacheStore.GetAsync("CacheKey", new TimeSpan(24, 0, 0),
                 async () =>
                  await _repo.GetAllAsync()
                  );
public static async Task < T > GetAsync < T > (this IRedisCacheStore source, string key, TimeSpan time, Func < Task < T >> fetch) where T: class {
 if (source.Exists(key)) {
  return await source.GetAsync < T > (key);
 } else {
  var result = fetch();

  if (result != null) {
   source.Set(key, result, time);
  }

  return await result;
 }
}

public async Task < List < ObjectType >> GetAllAsync() {
 var result = await _procExecutor.ExecuteProcAsync < ObjectType > ("Sproc", null);

 return (result ? ? new List < ObjectType > ()).ToList();
}

public async Task < IEnumerable < TResult >> ExecuteProcAsync < TResult > (string sproc, object param) {
  using(var conn = _connection.GetConnection()) {
   return await conn.QueryAsync < TResult > (sproc, param, commandType: CommandType.StoredProcedure);
  }
public static async TaskGetAsync(此IRedisCacheStore源代码、字符串键、时间跨度时间、Func>fetch)其中T:class{
if(source.Exists(key)){
返回wait source.GetAsync(键);
}否则{
var result=fetch();
如果(结果!=null){
source.Set(键、结果、时间);
}
返回等待结果;
}
}
公共异步任务>GetAllAsync(){
var result=await_proceducer.ExecuteProcAsync(“存储过程”,null);
返回(结果??新列表()).ToList();
}
公共异步任务>ExecuteProcAsync(字符串存储过程,对象参数){
使用(var conn=\u connection.GetConnection()){
return wait conn.QueryAsync(存储过程,参数,commandType:commandType.storedProcess);
}
这是我的redis缓存商店

public interface IRedisCacheStore
{
    bool Exists(string key);
    T Get<T>(string key);
    void Set<T>(string key, T value, TimeSpan expiredIn);
    void Remove(string key);

    Task<bool> ExistsAsync(string key);
    Task<T> GetAsync<T>(string key);
    Task SetAsync<T>(string key, T value, TimeSpan expiredIn);
    Task RemoveAsync(string key);
}
公共接口IRedisCacheStore
{
bool存在(字符串键);
T Get(字符串键);
无效集(字符串键、T值、TimeSpan expiredIn);
无效删除(字符串键);
任务存在同步(字符串键);
任务GetAsync(字符串键);
Task SetAsync(字符串键、T值、TimeSpan expiredIn);
任务RemoveAsync(字符串键);
}
问题在于:

var result = fetch();

if (result != null) {
   source.Set(key, result, time);
} 
fetch()
返回
Task
,这就是您试图存储在Redis缓存中的内容,任务(显然)不可序列化。只需使用:

var result = await fetch();

为什么要使用异步委托?为什么不简单地
()=>\u repo.GetAllAsync()
?或者甚至只是
\u repo.GetAllAsync
?我也尝试过这种方法,结果也一样,所以我尝试了异步()=>await,它也有相同的结果。客户端js显示挂起,当我调试它时,它只是继续,没有中断,似乎它已经完成了对所有代码请求的处理,除了,如前所述,您根本不需要异步委托,这里也有:var result=fetch();-这应该是var result=await fetch();然后将Task类型的变量存储在redis缓存中(通过Set),谁知道会发生什么呢。
async
死锁的最常见原因是,如果您正在同步等待
async
代码。您这样做了吗?您可以向代码显示您在此处显示的调用方法吗?理想情况下,提供一个。我应该在var result=fetch()中添加wait;