2014-11-03 15 views
6

phương thức này - doDayBegin(item.BranchId) mất nhiều thời gian để thực thi. Vì vậy, tôi đang sử dụng Parallel.ForEach để thực hiện song song. Khi tôi đang sử dụng bình thường foreach làm việc tốt, nhưng khi tôi đang sử dụng Parallel.ForEach, nó hiển thị lỗi này
Tham chiếu đối tượng không được đặt thành thể hiện của đối tượng.Lỗi 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); 
    } 

} 


đây là lỗi this error i am getting

những gì sẽ là vấn đề? tại sao tôi nhận được Session null. cách nào để giải quyết nó

Trả lời

19

HttpContext.Current được đặt cho mỗi chuỗi. Vì vậy, khi bạn kích hoạt nhiều chủ đề hơn bằng cách sử dụng Parallel.ForEach chủ đề mới của bạn không thể truy cập theo cách đó. Giải pháp sẽ là chuyển các giá trị cần thiết dưới dạng thông số theo cách thay vì dựa vào HttpContext.Current trong kho lưu trữ của bạn.

Có một số nguồn ở đây trên SO đã đề cập đến vấn đề này.

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

HttpContext.Current.Items in different thread

Access HttpContext.Current from different threads

1

Bạn nhận được lỗi bởi vì bạn đang cố gắng để có được những HttpContext từ một sợi mà không được chạy với mục đích đáp ứng một yêu cầu.

Thuộc tính HttpContext.Current sử dụng chuỗi này để xác định ngữ cảnh cần lấy, vì máy chủ web có thể chạy một số luồng để xử lý yêu cầu. Khi số Parallel.ForEach bắt đầu chủ đề mới, chúng sẽ không được kết nối với một số HttpContext.

Bạn cần chuyển theo thông tin mà phương thức cần trong lệnh gọi phương thức.

2

HttpContext.Current is null vì nó đang chạy trong "chủ đề không phải web". Nếu bạn chia nhỏ một số mã bằng cách sử dụng Thread mới (...) nó sẽ được chính xác như nhau. TPL phần nào che giấu điều này, nhưng bạn vẫn cần phải nhận ra rằng mỗi lần lặp trong Parallel.ForEach của bạn có khả năng chạy trong một luồng khác nhau và xử lý nó cho phù hợp.

Cụ thể, nếu bạn muốn sử dụng một số lớp hoặc phương pháp ngoài yêu cầu web (và Parallel.ForEach là cách sử dụng như vậy), bạn không thể sử dụng HttpContext.Current. Một cách giải quyết là phải vượt qua một cách rõ ràng HttpContext (hoặc HttpContextBase để cải thiện testability) trong các nhà xây dựng (hoặc như một tham số phương pháp)

dụ:

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



private static void DoSomething(HttpContext context) { 
} 
0

Tiếp tục thêm vào Bayu Alvian câu trả lời. Tôi đã có một vấn đề tương tự và tôi giải quyết nó bằng cách đi qua các bối cảnh như tham số nhưng bên trong phương pháp này tôi đã

'tên phương pháp' Thành viên không thể được truy cập với một ví dụ tham khảo

tôi giải quyết nó bằng cách làm một chút tinh chỉnh từ câu trả lời ở trên.

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

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

Gán ngữ cảnh cho HttpContext.Loại bỏ nó.

Các vấn đề liên quan