2014-04-04 5 views
7

मैं एफई सहायक वर्ग कि परिवर्तन async सहेजता है:इकाई की रूपरेखा 6.1.0 SaveChangesAsync

public async Task<int> SaveOrUpdateAsync<TEntity>(TEntity entity) 
     where TEntity : class, IContextEntity 
    { 
     if (entity.Id == 0) 
      context.Set<TEntity>().Add(entity); 
     else 
     { 
      TEntity dbEntry = context.Set<TEntity>().Find(entity.Id); 
      if (dbEntry != null) dbEntry = entity; 
     } 

     return await context.SaveChangesAsync(); 
    } 

public void Save() 
{ 
Task saveEntit1Async = repository.SaveOrUpdateAsync<Entity1>(entity1); 
Task saveEntity2Async = repository.SaveOrUpdateAsync<Entity2>(entity2); 
Task saveEntity3Async = repository.SaveOrUpdateAsync<Entity3>(Entity3); 

Task.WaitAll(saveEntit1Async, saveEntity2Async, saveEntity3Async); 

string test = "test"; 
) 

फोन पर

Task.WaitAll(saveEntit1Async, saveEntity2Async, saveEntity3Async); 

लाइन अटक जाती है और

string test = "test"; 

के लिए कभी नहीं हो जाता है लेकिन अगर मैं इसे चलाता हूं:

public void Save() 
{ 
repository.SaveOrUpdateAsync<Entity1>(entity1); 
repository.SaveOrUpdateAsync<Entity2>(entity2); 
repository.SaveOrUpdateAsync<Entity3>(Entity3); 

string test = "test"; 
) 

यह ठीक काम करता है, सभी परिवर्तनों को सहेजा जा रहा है और इसे करने के लिए

string test = "test"; 

क्यों

Task.WaitAll(saveEntit1Async, saveEntity2Async, saveEntity3Async); 

है आपरेशन जम जाता हो जाता है और कोड की अगली पंक्ति में कॉल गुजरता है कभी नहीं (स्ट्रिंग परीक्षण = "परीक्षण";)?

+1

बिना कार्य। प्रतीक्षा करें, सिस्टम निष्पादन के वर्तमान धागे को अवरुद्ध नहीं करता है और अगली पंक्ति निष्पादित हो जाती है, कार्य के साथ। प्रतीक्षा करें, वर्तमान थ्रेड तब तक इंतजार करेगा जब तक कि सभी परिचालन नहीं किए जाते हैं, फिर स्ट्रिंग टेस्ट = 'टेस्ट'; – Sherlock

+0

निष्पादित हो जाता है! लेकिन क्यों प्रतीक्षा हमेशा प्रतीक्षा करें पर! और दूसरी पंक्ति में कभी नहीं मिलता है? –

+0

आपके पास इस कार्य में अपवाद हो सकता है, जो कभी भी वापस नहीं आ सकता है, इसलिए यह हमेशा के लिए प्रतीक्षा करेगा – Sherlock

उत्तर

12

मैंने इसे समझ लिया!

यहां समस्या है जो हो रहा था, जब आप कार्य को "प्रतीक्षा करें" विधि के साथ प्रतीक्षा करते हैं या परिणाम को सीधे "परिणाम" संपत्ति से लेते हैं, तो आप मुख्य थ्रेड को उसी समय ब्लॉक करते हैं । अंततः कार्य थ्रेड पूल में उस विधि (SaveOrUpdateAsync (TENTITY इकाई)) के अंदर पूरा हो जाता है, यह मुख्य थ्रेड पर वापस पोस्ट करने के लिए निरंतरता का आह्वान करने जा रहा है (क्योंकि यह इसे कभी नहीं छोड़ा गया है), क्योंकि सिंक्रनाइज़ेशन कॉन्टेक्स्ट.क्यूरेंट उपलब्ध और कब्जा कर लिया गया है । लेकिन यहां एक समस्या है: मुख्य धागा "प्रतीक्षा करें" विधि से अवरुद्ध है और इस तरह मैं एक डेडलॉक प्राप्त कर रहा था!

डेडलॉक समस्या को ठीक करने के लिए मुझे संदर्भ के लिए कैप्चर किए गए संदर्भ को जारी रखने के लिए निर्दिष्ट करना था। SaveChangesAsync()।

public async Task<int> SaveOrUpdateAsync<TEntity>(TEntity entity) 
     where TEntity : class, IContextEntity 
    { 
     if (entity.Id == 0) 
      context.Set<TEntity>().Add(entity); 
     else 
     { 
      TEntity dbEntry = context.Set<TEntity>().Find(entity.Id); 
      if (dbEntry != null) dbEntry = entity; 
     } 

     return await context.SaveChangesAsync().ConfigureAwait(continueOnCapturedContext: false); 
    } 
+1

कार्य का उपयोग भी नहीं कर रहे हैं। प्रतीक्षा करें, बस प्रतीक्षा करें और अभी भी समस्या है। इस स्निपेट ने मेरा कोड तय किया। बहुत - बहुत धन्यवाद। – TombMedia

0

शायद मैं बेवकूफ जा रहा हूँ (!), लेकिन क्यों अपने कोड कहता है

if (dbEntry != null) dbEntry = entity; 

निश्चित रूप से अगर बयान होना चाहिए कि

if (dbEntry == null) dbEntry = entity; 

मैं सी # अशक्त-कोलेसिंग लगता है ऑपरेटर दोनों लाइनों को प्रतिस्थापित करने के लिए भी काम करेगा

TEntity dbEntry = context.Set<TEntity>().Find(entity.Id) ?? entity; 
संबंधित मुद्दे