2016-09-11 22 views
2

目的:Func for async进入死锁状态?

我使用Redis的高速缓存,并试图获得一个缓存值,如果不提供回购获取和设置缓存值。

问题:

客户端JS一直等下去,它似乎是某种类型的僵局

代码导致问题

return await _cacheStore.GetAsync("CacheKey", new TimeSpan(24, 0, 0), 
       async() => 
        await _repo.GetAllAsync() 
       ); 

代码的作品,但有点多余,因为我继续使用这种模式很多地方。

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; 

下面通过异步方法作为函数功能//可能的问题函数????? 功能通过上面的代码

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); 
    } 

这里堪称是我的Redis cacheStore

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); 
} 
+2

为什么你根本不使用异步委托?为什么不简单'()=> _repo.GetAllAsync()'?甚至只是'_repo.GetAllAsync'? –

+0

我试过这种方式,它产生了相同的结果,所以我试着用async()=>等待,它也有相同的结果。客户端js显示挂起,当我调试它只是继续,并没有打破任何地方,似乎喜欢它完成处理所有代码请求 –

+0

除了,如上所述,你不需要异步委托,也在这里:var result = fetch( ); - 这应该是var result = await fetch();.然后,您将任务类型为的变量存储在redis缓存中(通过Set),谁知道该做什么。 – Evk

回答

3

的问题是在这里:

var result = fetch(); 

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

fetch()回报Task<T>,那就是你想什么存储在Redis缓存中,Task(显然)不可序列化。只需使用:

var result = await fetch();