c# - Dead lock when retrieving several keys from Redis -
i'm trying result of queries redis (using stackexchange c# client) in parallel somehow i'm running in deadlock , not sure where
the method retrieving data:
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)) }; }
and methods fetching cached data redis are:
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); }
i think it's fine calling keyexpireasync this, because it's fine trigger , forget not sure if related (i tried removing , it's still blocked)
the source of deadlock snippet:
public livedata get(string sessionid) { return getasync(sessionid).result; }
instead, invoke proper way "async way":
public async task<livedata> get(string sessionid) { return await getasync(sessionid); }
invoking .result
can lead deadlocking, can using .wait()
api. also, looks of -- .keyexpireasync
needs awaited.
async task<redisvalue> getbasketasync(string key) { key = $"{key}{basketsuffix}"; var redisdb = redisconnection.connection.getdatabase(); await redisdb.keyexpireasync(key, _expire); return await redisdb.stringgetasync(key); }
i understand thought process on not using await
keyword on .keyexpireasync
call if writing code want await
have demonstrated. code smell have fire-and-forget, , can avoided.
Comments
Post a Comment