c# - DataTable.Rows.Add():集合被修改;枚举操作可能无法执行
问题描述
我有一个跨不同线程共享的数据集。但是每个 DataTable 仅在特定线程上独占使用。时不时地我得到这个错误:Collection was modified; enumeration operation may not execute.
这是我的代码:
DataTable dt = null;
lock (ds)
{
dt = ds.Tables.Add("FeedbackSummary");
}
dt.Columns.Add("FeedbackId", typeof(int));
dt.Columns.Add("Question", typeof(string));
dt.Columns.Add("Total Ratings", typeof(int));
dt.Columns.Add("Total Votes", typeof(int));
List<Feedback> feedbacks = GetFeedbacks();
foreach (Feedback f in feedbacks)
{
int id = f.FeedbackId;
DataRow dr = dt.Select("FeedbackId=" + id).FirstOrDefault();
if (dr == null)
{
dr = dt.NewRow();
dr["FeedbackId"] = id;
dr["Question"] = f.Question;
dr["Total Ratings"] = 0;
dr["Total Votes"] = 0;
dt.Rows.Add(dr); //error occurs here. dt.Rows.Count is 0
}
dr["Total Votes"] = (int)dr["Total Votes"] + f.TotalVotes;
dr["Total Ratings"] = (int)dr["Total Ratings"] + f.TotalRating;
}
dt.Rows.Add
即使 DataTable 未共享且未foreach
对 DataTable 的行执行,它也会发生。更糟糕的是,它会间歇性地发生。
完整的错误(来自异常的 StackTrace):
at System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()
at System.Data.ConstraintEnumerator.GetNext()
at System.Data.DataTable.CascadeAll(DataRow row, DataRowAction action)
at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent)
at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean suppressEnsurePropertyChanged, Int32 position, Boolean fireEvent, Exception& deferredException)
at System.Data.DataTable.InsertRow(DataRow row, Int64 proposedID, Int32 pos, Boolean fireEvent)
at System.Data.DataRowCollection.Add(DataRow row)
at Website.GenerateFeedbackSummary(DataSet ds) in C:\Pro\Website\Website\Utils\Reports.Summary.cs:line 88
at Website.ReportUtils.<>c__DisplayClass80_0.<GenerateReportSummary>b__3() in C:\Pro\Website\Website\Utils\ReportUtil.cs:line 565
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
任何想法?
谢谢...
这是 GetFeedbacks() 的代码
using (EFOrderDB ef = DBProvider.Create())
{
return DBProvider.GetRetryPolicy().ExecuteAction<List<Feedback>>(() =>
{
return (from rec in ef.Feedbacks.AsNoTracking()
select rec).Take(20).ToList<Feedback>();
});
}
解决方案
推荐阅读
- java - 如何在计算器上用 Int 显示结果?
- c++ - 我相信 [dcl.typedef]/1 有缺陷,否则我错过了什么?
- pytorch - 用于预测字符的 LSTM:训练循环中的单元状态和隐藏状态
- python - 将 Pandas 数据框转换为每列字典列表的最佳方法
- sql - 两个日期之间的完整日历月
- python - 直方图中的断轴和 Python 中的概率分布
- ios - 如何将核心数据对象分组为 UITableView 的数据源
- node.js - Alexa Smart Home Skill - 需要帮助才能发出 http 请求
- javascript - 在 JavaScript/ES6/ES7 中迭代数组中的嵌套值
- html - 采用柔性设计的固定头