2014-12-02 14 views
6

यह पता लगाने की कोशिश कर रहा है कि यह कोड क्यों लटकता है। मैं परीक्षण के नीचे 3 लाइनों में से किसी एक को हटा सकता हूं और यह लटका नहीं होगा, लेकिन सभी 3 एक साथ इसे लटकते हैं। किसी भी तरह की सहायता का स्वागत किया जाएगा!StackExchange.Redis async कॉल

[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

आप 'टास्क.रुन' का उपयोग क्यों करते हैं और क्यों प्रतीक्षा करें() '? – i3arnon

+0

मुझे लगता है कि 'टास्क.रुन (() => AddAsync (डीबी, "टेस्ट", "1") में समस्या है।) प्रतीक्षा करें(); '। यहाँ आप डेडलॉक है। –

+0

यह मेरे कोड का सरलीकृत संस्करण है। यथासंभव सरल होने के लिए इसे तोड़ने की कोशिश कर रहा है। मैं यह समझने की कोशिश कर रहा हूं कि क्या हो रहा है। –

उत्तर

10

यह मिश्रण Wait और await से एक सिंक संदर्भ गतिरोध की तरह मेरे लिए लग रहा है। इसीलिए आप कभी नहीं कि करते हैं - ("गिल्बर्ट और सुलिवान" में स्विच): well, hardly ever!

यदि यह मदद करता है, मैं संदिग्ध कि Wait सबट्री में await को हटाने इसे ठीक होगा - जो होना चाहिए तुच्छ कि पेड़ के साथ बदला जा सकता है के बाद से एक छोटी सी पास होना:

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

महत्वपूर्ण बात है कि यहाँ SE.Redis आंतरिक रूप से नजरअंदाज सिंक-प्रसंग (पुस्तकालय कोड के लिए सामान्य), तो यह गतिरोध नहीं होना चाहिए ।

लेकिन आखिरकार: मिश्रण Wait और await एक अच्छा विचार नहीं है। डेडलॉक्स के अलावा, यह "एसिंक पर सिंक" है - एक विरोधी पैटर्न।

संबंधित मुद्दे