StackExchange.Redis异步调用挂起

时间:2014-12-02 21:08:16

标签: c# async-await stackexchange.redis

试图找出此代码挂起的原因。我可以删除测试底部的3行中的任何一行,但它不会挂起,但所有3行都会挂起。任何帮助将不胜感激!

[Fact]
public async Task CanAddValuesInParallel() {
    var muxer = ConnectionMultiplexer.Connect("localhost");
    var db = muxer.GetDatabase();

    await AddAsync(db, "test", "1");
    await db.KeyDeleteAsync("test");

    Task.Run(() => AddAsync(db, "test", "1")).Wait();
}

public async Task<bool> AddAsync(IDatabase db, string key, string value) {
    return await db.StringSetAsync(key, value, null, When.NotExists);
}

1 个答案:

答案 0 :(得分:11)

听起来像是混合Waitawait的同步上下文死锁。这就是为什么你从不这样做 - (换成“Gilbert and Sullivan”): well, hardly ever!

如果它有帮助,我怀疑删除await子树中的Wait将修复它 - 这应该是微不足道的,因为该树可以用一个简单的传递替换-thru:

public Task<bool> AddAsync(IDatabase db, string key, string value) {
    return db.StringSetAsync(key, value, null, When.NotExists);
}

这里重点是SE.Redis在内部绕过sync-context(库代码正常),所以它不应该有死锁。

但最终:混合Waitawait不是一个好主意。除了死锁之外,这是“同步异步” - 一种反模式。