2014-11-03 10 views
6

यह विधि - doDayBegin(item.BranchId) निष्पादित करने में लंबा समय लग रहा है। इसलिए मैं समानांतर निष्पादित करने के लिए Parallel.ForEach का उपयोग कर रहा हूं। जब मैं सामान्य foreach लूप का काम कर रहा हूं तो ठीक काम करता है लेकिन जब मैं Parallel.ForEach का उपयोग कर रहा हूं तो यह त्रुटि
ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट के उदाहरण पर सेट नहीं है।समांतर। फॉरएच त्रुटि HttpContext.Current

public ActionResult Edit([DataSourceRequest] DataSourceRequest request) 
     { 
      try 
      { 
       JavaScriptSerializer js = new JavaScriptSerializer(); 
       List<DB0010020Vm> _listDB0010020Vm = new List<DB0010020Vm>(); 

       string dataDB0010020vm = Request.Form["griddetailsvm"]; 
       if (!string.IsNullOrEmpty(dataDB0010020vm)) 
       { 
        _listDB0010020Vm = js.Deserialize<List<DB0010020Vm>>(dataDB0010020vm). 
        Where(d => d.IsValid == "YES").ToList(); 
       } 
       DateTime start = DateTime.UtcNow; 


       Parallel.ForEach(_listDB0010020Vm, item => 
       { 
        doDayBegin(item.BranchId); 
       }); 

       DateTime end = DateTime.UtcNow; 
       TimeSpan duration = end - start; 
       return Json(new 
       { 
        success = true, 
        message = "Day Begin Process Completed Successfully!" + duration 
       }); 
      } 
      catch (Exception e) 
      { 
       return Json(new 
       { 
        success = false, 
        message = e.Message 
       }); 

      } 
     } 

    public void doDayBegin(int BranchId) 
{ 
    var httpContext = System.Web.HttpContext.Current; 
    IDB0010020Repository _idDB0010020Repository = new DB0010020Repository(); 
    IDB0010044Repository _idDB0010044Repository = new DB0010044Repository(); 

    EBS.DAL.Model.DB0010020 branchDetails = _idDB0010020Repository.FindOne(d => d.BranchId == BranchId); 
    if (branchDetails == null) 
    { 
     ModelState.AddModelError("", "Branch not found!"); 
    } 
    else 
    { 
     try 
     { 
      DateTime LastOpenDate = DateTime.ParseExact(Request.Form["LastOpenDate"].ToString(), "dd/MM/yyyy", CultureInfo.InvariantCulture); 
     // branchDetails.LastOpenDate = LastOpenDate; 
    //  branchDetails.LastOpenDate = Convert.ToDateTime(Request.Form["LastOpenDate"].ToString()); 


     } 
     catch (Exception e) 
     { 
      // branchDetails.LastOpenDate = Convert.ToDateTime("2014-07-25 00:00:00.000"); 
     } 


     OperationStatus status = _idDB0010020Repository.UpdateAndSave(branchDetails); 
     if (status != null && !status.Status) 
      ModelState.AddModelError("Updation failed", status.ExceptionMessage); 
    } 

    EBS.DAL.Model.DB0010044 dayBegin = new DB0010044(); 
    dayBegin.BankId = 1; 
    dayBegin.BranchId = BranchId; 
    dayBegin.DayBeginFlag = 1; 
    //added d 
    DateTime DayDate = DateTime.ParseExact(Request.Form["LastOpenDate"].ToString(), "dd/MM/yyyy", CultureInfo.InvariantCulture); 
    dayBegin.DayDate = DayDate; 
    //added d 

    // dayBegin.DayDate = Convert.ToDateTime(Request.Form["LastOpenDate"]); 
    dayBegin.DayEndFlag = 0; 
    dayBegin.DayEndStage = 1; 
    dayBegin.DayReopenFlag = 0; 
    OperationStatus status2 = _idDB0010044Repository.AddAndSave(dayBegin); 
    if (status2 != null && !status2.Status) 
     ModelState.AddModelError("Updation failed", status2.ExceptionMessage); 
    else 
    { 
     CreateInwardSessionsForBranch(BranchId); 
     CreateOutwardSessionsForBranch(BranchId); 
    } 

} 


इस त्रुटि this error i am getting

क्या मुद्दा होगा? मुझे सत्र शून्य क्यों मिल रहा है। इसे हल करने का तरीका

उत्तर

19

HttpContext.Current प्रति थ्रेड सेट है। तो जब आप Parallel.ForEach का उपयोग करके अधिक धागे को आग लगाते हैं तो आपके नए धागे इस तरह से इसका उपयोग नहीं कर सकते हैं। समाधान आपके भंडारों में HttpContext.Current पर निर्भर होने के बजाय आवश्यक मानों को पैरामीटर के रूप में पारित करना होगा।

एसओ पर ऐसे कई स्रोत हैं जो पहले से ही इस समस्या को कवर करते हैं।

The cross-thread usage of "HttpContext.Current" property and related things

HttpContext.Current.Items in different thread

Access HttpContext.Current from different threads

1

क्योंकि आपको लगता है कि एक अनुरोध का जवाब करने के उद्देश्य से नहीं चल रहा है एक धागे से HttpContext पाने के लिए कोशिश कर रहे हैं आप त्रुटि मिलती है।

HttpContext.Current संपत्ति उस संदर्भ को पहचानने के लिए धागे का उपयोग करती है, क्योंकि वेब सर्वर अनुरोधों को संभालने के लिए कई धागे चला सकता है। चूंकि Parallel.ForEach नए धागे शुरू करता है, इसलिए वे HttpContext से कनेक्ट नहीं होंगे।

आपको विधि के साथ कॉल में आवश्यक जानकारी के साथ पास करने की आवश्यकता है।

2

HttpContext.Current शून्य है क्योंकि यह "गैर-वेब धागे" में चल रहा है। यदि आपने नए थ्रेड (...) का उपयोग करके कुछ कोड फोर्क किया है तो यह वही होगा। टीपीएल कुछ हद तक इसे छुपाता है, लेकिन आपको अभी भी यह समझने की जरूरत है कि आपके समांतर में प्रत्येक पुनरावृत्ति। फॉरएच संभावित रूप से एक अलग थ्रेड में चला सकता है, और इसके अनुसार इसका इलाज कर सकता है।

विशेष रूप से, यदि आप वेब अनुरोध से कुछ कक्षा या विधि का उपयोग करना चाहते हैं (और समानांतर। फॉरएच ऐसा उपयोग है) तो आप केवल HttpContext.Current का उपयोग नहीं कर सकते हैं। का संभावित हल (या सुधार testability के लिए HttpContextBase) स्पष्ट रूप से HttpContext पारित करने के लिए है निर्माता में (या एक विधि पैरामीटर के रूप में)

उदाहरण:

var context = HttpContext.Current; 
Parallel.ForEach(items, item => 
    { 
     DoSomething(context); 
    } 
); 



private static void DoSomething(HttpContext context) { 
} 
0

इसके अलावा Bayu Alvian जवाब देने के लिए जोड़ने। मैं एक ऐसी ही समस्या थी और मैं पैरामीटर के रूप में संदर्भ पारित करके इसे हल लेकिन विधि के अंदर मैं

मिला

सदस्य 'विधि नाम' एक उदाहरण के साथ पहुँचा नहीं जा सकता संदर्भ

मैं से थोड़ी ट्वीक करके इसे हल उपर्युक्त उत्तर

// Get the new context 
HttpContext context = HttpContext.Current; 
Parallel.ForEach(items, item => 
    { 
     DoSomething(context); 
    } 
); 

private static void DoSomething(HttpContext context) { 
HttpContext.Current = context; 
} 

संदर्भ को HttpContext.Current को संदर्भित करना इसे हटा देता है।

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