此方法 - 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);
}
}
}
这是错误
会出现什么问题?
答案 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 }}