2014-12-02 7 views
6

Próbuję ustalić, dlaczego ten kod się zawiesza. Mogę usunąć dowolną z 3 linii na dole testu i nie zawiesi się, ale wszystkie 3 razem sprawią, że się zawiesi. Każda pomoc będzie bardzo ceniona!Połączenie asynchroniczne StackExchange.Redis zawiesza się

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

Dlaczego używasz 'Task.Run' i dlaczego' Czekaj() '? – i3arnon

+0

Myślę, że problem w 'Task.Run (() => AddAsync (db," ​​test "," 1 ")). Czekaj();'. Tutaj masz impas. –

+0

To jest uproszczona wersja mojego kodu. Próbuje go rozbić tak, aby był jak najbardziej uproszczony. Próbuję zrozumieć, co się dzieje. –

Odpowiedz

10

To brzmi dla mnie jak impasu sync-kontekstowego od mieszania Wait i await. Który jest dlaczego nigdy zrobić - (przełączanie na „Gilberta i Sullivana”): well, hardly ever!

Jeśli to nie pomaga, ja podejrzany że usuwając await w Wait poddrzewie będzie to naprawić - które powinny być trywialny ponieważ drzewa można zastąpić trywialne pass-thru:

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

ważną rzeczą jest to, że SE.Redis omija sync kontekst wewnętrznie (normalna dla kodu biblioteki), więc nie powinno mieć impas .

Ale ostatecznie: mieszanie Wait i await nie jest dobrym pomysłem. Oprócz zakleszczeń jest to "synchronizacja przez asynchroniczne" - anty-wzór.