2014-12-02 8 views
6

Versuchen, herauszufinden, warum dieser Code hängt. Ich kann eine der 3 Zeilen am Ende des Tests entfernen und es wird nicht hängen, aber alle 3 zusammen macht es hängen. Jede Hilfe würde sehr geschätzt werden!StackExchange.Redis async-Aufruf hängt

[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

Warum verwenden Sie 'Task.Run' und warum' Wait() '? – i3arnon

+0

Ich denke Problem in 'Task.Run (() => AddAsync (db," ​​test "," 1 ")). Wait();'. Hier haben Sie eine Sackgasse. –

+0

Dies ist die vereinfachte Version meines Codes. Versuchen, es zu brechen, um so vereinfacht wie möglich zu sein. Ich versuche zu verstehen, was vor sich geht. –

Antwort

10

Es klingt für mich wie ein Sync-Kontext Deadlock von Wait und await mischen. Welches ist, warum Sie nie tun - (Schalt in „Gilbert und Sullivan“): well, hardly ever!

Wenn es hilft, ich Verdächtiger dass die await im Wait Teilbaum zu entfernen wird es beheben - was sein sollte trivial, da kann der Baum mit einem trivialen Pass-thru ersetzt:

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

Der wichtige Punkt hier ist, dass SE.Redis intern Sync-Kontext umgeht (normal für Bibliotheks-Code), so sollte es nicht um den Stillstand hat .

Aber letztlich: Mischen Wait und await ist keine gute Idee. Zusätzlich zu Deadlocks ist dies "Sync async" - ein Anti-Pattern.

Verwandte Themen