1

Ich versuche, das Ergebnis dieser Abfragen zu erhalten, Redis parallel (Stack C# Client verwenden), aber irgendwie in einer Sackgasse, ich laufe und nicht sicher, woDead-Lock, wenn mehrere Schlüssel von Redis Abrufen

Verfahren die Daten für die Beschaffung von:

public LiveData Get(string sessionId) 
{ 
    return GetAsync(sessionId).Result; 
} 

private async Task<LiveData> GetAsync(string sessionId) 
{ 
    var basketTask = GetBasketAsync(sessionId); 
    var historyTask = GetHistoryAsync(sessionId); 
    var capturedDataTask = GetCapturedDataAsync(sessionId); 

    var basket = await basketTask; 
    var history = await historyTask; 
    var capturedData = await capturedDataTask; 

    return new LiveData 
    { 
     Basket = basket.IsNullOrEmpty 
      ? new List<Product>() 
      : JsonConvert.DeserializeObject<List<Product>>(basket), 
     History = history.Select(cachedProduct 
      => JsonConvert.DeserializeObject<Product>(cachedProduct.Value.ToString())).ToList(), 
     CapturedData = capturedData.ToDictionary<HashEntry, string, object>(
      hash => hash.Name, hash => JsonConvert.DeserializeObject(hash.Value)) 
    }; 
} 

und die Methoden für die zwischengespeicherten Daten aus redis holen sind:

private async Task<RedisValue> GetBasketAsync(string key) 
{ 
    key = $"{key}{BasketSuffix}"; 
    var redisDb = RedisConnection.Connection.GetDatabase(); 
    redisDb.KeyExpireAsync(key, _expire); 

    return await redisDb.StringGetAsync(key); 
} 

private async Task<HashEntry[]> GetHistoryAsync(string key) 
{ 
    key = $"{key}{HistorySuffix}"; 
    var redisDb = RedisConnection.Connection.GetDatabase(); 
    redisDb.KeyExpireAsync(key, _expire); 

    return await redisDb.HashGetAllAsync(key); 
} 

private async Task<HashEntry[]> GetCapturedDataAsync(string key) 
{ 
    key = $"{key}{CapturedDataSuffix}"; 
    var redisDb = RedisConnection.Connection.GetDatabase(); 
    redisDb.KeyExpireAsync(key, _expire); 

    return await redisDb.HashGetAllAsync(key); 
} 

ich denke, es ist in Ordnung, die KeyExpireAsync wie diese nennen, nur weil ich t ist in Ordnung auslösen und vergessen, aber nicht sicher, ob das zusammenhängen könnte (ich habe sogar versucht, es zu entfernen und es ist immer noch blockiert)

Antwort

3

Die Quelle der Sackgasse ist dieser Ausschnitt:

public LiveData Get(string sessionId) 
{ 
    return GetAsync(sessionId).Result; 
} 

Stattdessen rufen sie die richtiger Weg „async der ganzen Weg“:

public async Task<LiveData> Get(string sessionId) 
{ 
    return await GetAsync(sessionId); 
} 

.Result Aufrufe zu Deadlocks führen kann, wie kann die .Wait() API. Auch vom Aussehen her - die .KeyExpireAsync muss erwartet werden.

async Task<RedisValue> GetBasketAsync(string key) 
{ 
    key = $"{key}{BasketSuffix}"; 
    var redisDb = RedisConnection.Connection.GetDatabase(); 
    await redisDb.KeyExpireAsync(key, _expire); 

    return await redisDb.StringGetAsync(key); 
} 

Ich verstehe Ihren Denkprozess auf nicht das await Schlüsselwort auf den .KeyExpireAsync Anruf verwenden, aber wenn ich diesen Code geschrieben haben würde ich ganz sicher zu await es will, wie ich gezeigt haben. Es ist ein Code-Geruch, um ein Feuer-und-vergessen zu haben, und kann leicht vermieden werden.

Verwandte Themen