2015-02-04 7 views
8

मैं निम्नलिखित कोड का प्रयास कर रहा हूं, इसमें दो भाग हैं, एक प्रिज्म के माध्यम से नेविगेशन है। जब नेविगेशन की अनुमति है तो मैं एक गहरा भार अतुल्यकालिक रूप से शुरू कर रहा हूं लेकिन प्रत्येक बार एक नए संदर्भ के साथ। यहाँयूओयू - पिछले एसिंक्रोनस ऑपरेशन से पहले इस संदर्भ पर एक दूसरा ऑपरेशन शुरू हुआ

public void OnNavigatedTo(NavigationContext navigationContext) 
{ 
    int relatieId = (int)navigationContext.Parameters["RelatieId"]; 
    if (_relatie != null && _relatie.RelatieId == relatieId) return; 

    loadRelatieAsync(relatieId); 
} 

public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback) 
{ 
    bool navigationAllowed = true; 
    continuationCallback(navigationAllowed); 
} 
कोई समस्या नहीं: बाद में कोड में मैं नेविगेशन जो इस तरह लोड नहीं कर रहे हैं लेकिन नीचे कोड भी काम नहीं करता है तो रद्द बाद में ;-)

नेविगेशन तर्क के लिए एक मामला है लंबित रद्द करना चाहते हैं

गहरी लोड हो रहा है तर्क:

private async Task loadRelatieAsync(int relatieId) 
{ 
    try 
    { 
     await Task.Run(async() => 
     { 

      _unitOfWork = _UnitOfWorkFactory.createUnitOfWorkAsync(); 

      IEnumerable<Relatie> relaties = await getRelatieAsync(_unitOfWork, relatieId).ConfigureAwait(true); 

      _relatieTypeTypes = await getRelatieTypeTypesAsync(_unitOfWork, relatieId).ConfigureAwait(true); 
      _relatie = relaties.FirstOrDefault(); 

      _unitOfWork.Dispose(); 
     }).ConfigureAwait(true); 

     processRelatie(_relatie); 

     processRelatieTypes(_relatie, _relatieTypeTypes); 
    } 
    catch (Exception Ex) 
    { 

     MessageBox.Show(Ex.Message); 
     throw; 
    } 

} 

private async Task<IEnumerable<Relatie>> getRelatieAsync(IUnitOfWorkAsync unitOfWork, int relatieId) 
{ 

    IEnumerable<Relatie> relaties = null; 
    try 
    { 
     IRepositoryAsync<Relatie> relatieRepository = unitOfWork.RepositoryAsync<Relatie>(); 
     relaties = await relatieRepository 
      .Query(r => r.RelatieId == relatieId) 
      .Include(i => i.BegrafenisOndernemer) 
      .SelectAsync() 
      .ConfigureAwait(false); 

     IRepositoryAsync<Adres> adresRepository = unitOfWork.RepositoryAsync<Adres>(); 
     //exception is thrown after executing following line 
     var adressen = await adresRepository 
      .Query(r => r.RelatieId == relatieId) 
      .Include(i => i.AdresType) 
      .SelectAsync() 
      .ConfigureAwait(false); 
     _relatieTypeRepository = unitOfWork.RepositoryAsync<RelatieType>(); 
     var relatieTypes = await _relatieTypeRepository 
      .Query(r => r.RelatieId == relatieId) 
      .SelectAsync() 
      .ConfigureAwait(false); 
    } 
    catch (Exception Ex) 
    { 
     MessageBox.Show(Ex.Message);//exception is shown here 
     throw; 
    } 
    return relaties; 
} 

private async Task<IEnumerable<RelatieTypeType>> getRelatieTypeTypesAsync(IUnitOfWorkAsync unitOfWork, int relatieId) 
{ 

    IEnumerable<RelatieTypeType> relatieTypeTypes = null; 
    try 
    { 
     IRepositoryAsync<RelatieTypeType> relatieTypeTypeRepository = 
      unitOfWork.RepositoryAsync<RelatieTypeType>(); 

     relatieTypeTypes = await relatieTypeTypeRepository 
      .Query() 
      .SelectAsync() 
      .ConfigureAwait(false); 

    } 
    catch (Exception Ex) 
    { 
     MessageBox.Show(Ex.Message); 
     throw; 
    } 
    return relatieTypeTypes; 
} 

जैसे मैं इंतजार करना भूल गया मैं हो रही अपवाद रखने के लिए, लेकिन इस मामले कभी नहीं है। जब भी मैं जीयूआई थ्रेड पर निरंतरता चाहता हूं तो मैं कॉन्फ़िगरवाइट (सत्य) का भी सही उपयोग करता हूं। लेकिन मैं इस त्रुटि को डीप्लोडिंग तर्क में प्राप्त करता रहता हूं। काम और भंडार वर्गों की इकाई भी एसिंक प्रतीक्षा तंत्र का उपयोग करती है लेकिन वहां भी मैं ठीक से इंतजार कर रहा हूं।

पिछले एसिंक्रोनस ऑपरेशन पूर्ण होने से पहले इस संदर्भ पर एक दूसरा ऑपरेशन शुरू हुआ। यह सुनिश्चित करने के लिए 'प्रतीक्षा करें' का प्रयोग करें कि इस संदर्भ पर किसी अन्य विधि को कॉल करने से पहले किसी भी एसिंक्रोनस ऑपरेशंस पूर्ण हो गए हैं। किसी भी इंस्टेंस सदस्यों को थ्रेड सुरक्षित होने की गारंटी नहीं है।

संपादित (हटाया लकड़हारा कोड कोड के आकार को कम करने के लिए)

+0

कृपया ध्यान दें कि createUnitOfWorkAsync() एक असीमित विधि नहीं है। यह सिर्फ एक वर्ग बनाता है जो एसिंक प्रतीक्षा पैराडाइम का समर्थन करता है। –

+1

'createUnitOfWorkAsync' एक * नया * संदर्भ बनाता है, सही? –

+1

'कॉन्फ़िगरएवाइट (सत्य);' यह पहला टाइमर है .. –

उत्तर

12

समस्या इस कोड है। पहले से ही निष्पादित परिदृश्य उसके बजाय उस नए यूनिटऑफवर्क का उपयोग करता है क्योंकि यह अधिलेखित है। स्पॉट करने के लिए इतना आसान नहीं है, लेकिन एक साधारण दौड़ की स्थिति है। मैंने स्थानीय चर द्वारा सभी इंस्टेंस चर को प्रतिस्थापित करके पाया और फिर समस्या निराश हुई।

0

यह शायद इस सवाल का जवाब नहीं है, लेकिन अपने कोड पर एक सामान्य लग रहे है।

वर्तमान थ्रेड उपलब्ध रखने के लिए async/await का मुख्य उद्देश्य है। यह यूआई थ्रेड को अवरुद्ध करने और आपके ऐप को उत्तरदायी रखने में मदद करता है।

आप पहले से ही यह सुनिश्चित कर रहे हैं कि आपकी गहरी लोडिंग थ्रेडपूल थ्रेड पर होती है, क्योंकि आप इसे पूरी तरह से कार्य का उपयोग शुरू कर रहे हैं। Run()। आप अपने लोडिंग तंत्र में EntityFramework के डिफ़ॉल्ट सिंक्रोनस विधियों का उपयोग करके शायद अपनी अधिकांश समस्याओं का सामना कर सकते हैं।

पहले देखो में, आपका कोड ठीक एसिंक कॉल के रूप में दिखता है। हो सकता है कि आपकी गहरी लोडिंग कई बार ट्रिगर हो? जब परिदृश्य को दूसरी बार यह एक नया उदाहरण के साथ ओवरराइट है शुरू होता है

_unitOfWork = _UnitOfWorkFactory.createUnitOfWorkAsync(); 

IEnumerable<Relatie> relaties = await getRelatieAsync(_unitOfWork, relatieId).ConfigureAwait(true); 

_relatieTypeTypes = await getRelatieTypeTypesAsync(_unitOfWork, relatieId).ConfigureAwait(true); 
_relatie = relaties.FirstOrDefault(); 

_unitOfWork.Dispose(); 

UnitOfWork, एक उदाहरण चर रहा है:

+0

टिप्पणी के लिए धन्यवाद, मैं इसे इस तरह से कर रहा हूं क्योंकि मैं रद्दीकरण टोकन का उपयोग करके अगली वृद्धि में ऑपरेशन को रद्द करने में सक्षम होना चाहता हूं। विधि लोड RelatieAsync को कई बार कहा जाता है और एक साथ चल रहा है क्योंकि अभी तक कोई रद्दीकरण नहीं है, लेकिन इससे कोई फर्क नहीं पड़ता क्योंकि मैं हर बार एक अलग संदर्भ का उपयोग कर रहा हूं। यह यूनिटफवर्क निर्माण के नीचे बनाया गया है। आप सही हैं कि मैं जितना संभव हो सके जीयूआई थ्रेड को अनवरोधित करने की कोशिश कर रहा हूं लेकिन मैं लंबित नेविगेशन ऑपरेशन को रद्द करने में भी सक्षम होना चाहता हूं –

+0

आप अभी भी अपने परिचालनों के बीच रद्दीकरण अनुरोधों की जांच कर सकते हैं, इससे कोई फर्क नहीं पड़ता। –

+0

आप अभी क्यों जांच नहीं करते हैं, अगर लोडिंग ऑपरेशन पहले ही शुरू हो चुका है और यह कार्य है, तो यह पहले से मौजूद है? क्या आप अपने संदर्भ के बारे में भी 100% निश्चित हैं? क्योंकि जब चल रहे लेनदेन आपकी त्रुटि का कारण बनते हैं, तो शायद यह समस्या है। –

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