Parallel.ForEach显示dbcontext的错误

时间:2014-11-03 05:59:08

标签: c# asp.net-mvc linq entity-framework parallel-processing

此方法 - doDayBegin(item.BranchId)需要很长时间才能执行。所以我使用Parallel.ForEach并行执行它。当我使用正常的foreach循环工作正常,但当我使用Parallel.ForEach它显示此错误
创建模型时无法使用上下文Parallel.ForEach

 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)
        {

            using (var dbThread = new NeoSampleDBEntities()) // new db connection
            {


                EBS.DAL.Model.DB0010020 branchDetails = _idDB0010020Repository.FindOne(d => d.BranchId == BranchId);
            if (branchDetails == null)
            {
                ModelState.AddModelError("", "Branch not found!");
            }
            else
            {
                branchDetails.LastOpenDate = Convert.ToDateTime(Request.Form["LastOpenDate"]);

                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;
            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

会出现什么问题?

2 个答案:

答案 0 :(得分:0)

我的猜测是,当调用parallel.foreach时,尚未计算_listDB0010020Vm。如果你在标准的非并行foreach中单步执行代码,它将通过跳过.where选择行,进入foreach,然后当它需要列表值时显示这一点,步骤next将显示它跳回到where选择器。我相信List.ToArray会强制它计算。尝试将该结果支付给并行循环。

答案 1 :(得分:0)

您在NeoSampleDBEntities方法中创建了DbContext doDayBegin的新实例,但是您使用了存储库的现有(并且据我所知,单个)实例{ {1}},可能封装了自己的_idDB0010020Repository实例或在构造时传入的预先存在的DbContext实例。

您看到的错误是第二个线程调用DbContext进行<repo>.FindOne方法调用的结果,同时由于第一个线程调用{{1}而生成模型}}。即使模型创建完成,您也很可能遇到冲突,因为DbContext不是线程安全的。

根据您提出的建议,我的建议是在<repo>.FindOne方法的DbContext语句中创建一个新的repo,而不是using {{1 }}