qak*_*mak 0 .net c# linq plinq
这是我的代码:
Parallel.ForEach(Students, item =>
{
StudentModel studentModel = new StudentModel(item);
// Maybe he/she has alot of name
foreach (var words in studentModel.StudentNames.Split(','))
{
if (string.IsNullOrWhiteSpace(words))
return;
string tempWords = words.Trim();
// add it to student names list
STUDENT_NAMES.Where(x => x.SearchWords == tempWords).FirstOrDefault().student.Add(studentModel);
}
// add it to student list
STUDENT_MODELS.Add(studentModel);
});
Run Code Online (Sandbox Code Playgroud)
我想做的是,我得到了学生名单.将其转换为学生模型,获取学生姓名(因为一个学生有很多名字),然后我将名字添加到名单,这是因为可能以后我需要得到同名学生并做一些事情......最后添加学生到学生模特名单.
问题发生在:
STUDENT_NAMES.Where(x => x.SearchWords == tempWords).FirstOrDefault().student.Add(studentModel);
Run Code Online (Sandbox Code Playgroud)
这个地方总是发生:System.IndexOutOfRangeException
我已经将Paralle.Foreach更改为Parallel.For,并将foreach更改为for,但没有任何更改.我必须使用Parallel,因为学生数量大约为100000,如果我只使用foreach替换Parallel.Foreach,则需要160+秒,如果我锁定那个地方.....还是慢......如果使用Parallel. Foreach,它将使用20秒左右,但我无法处理异常.
我已经尝试用这个替换它:
StudentNames name = STUDENT_NAMES.Where(x => x.SearchWords == tempWords).FirstOrDefault();
if (null != name)
name.student.Add(StudentModel);
Run Code Online (Sandbox Code Playgroud)
但问题仍然发生在某些时候........如果我只是尝试...抓住并忽略它,然后当我以后访问STUDENT_NAMES列表时,它仍然抛出异常....... .....
我也尝试使用ConcurrentBag <>,但速度很慢....我不能接受它.....
有没有什么好方法可以处理它.非常感谢你!
更新:
我无法理解的是:为什么我不能在Parallel.Foreach中的列表中添加一些东西.我认为Parallel.Foreach将使用很多线程,但事件使用多个线程添加对它没有任何问题.
线程1添加和线程2添加没有任何关系....为什么会发生该异常?
Ser*_*rvy 11
List不是设计为从多个线程访问.这样做是不安全的.您可以遇到各种各样的问题,包括索引异常,添加丢失,重复,其他类型的错误,几乎任何问题.
我也尝试使用ConcurrentBag <>,但速度很慢....我不能接受它.....
当两个选项中只有一个实际有效时,性能无关紧要.您可以使代码正常工作并花费尽可能长的代码,或者您可以使用不起作用的代码,以及执行错误的速度与此无关.
当然,您还有其他选择,例如查看重新设计程序的方法,以使用本质上更有效的算法,而不是尝试做一些非常低效的事情,而只是将其并行化以隐藏这一事实.您目前正在列表中执行线性搜索以找到另一个集合中每个项目的匹配项目这一事实是一个相当糟糕的设计; 你应该使用一个可以更有效地搜索的集合,例如a HashSet.虽然不知道问题的细节,但我们无法说出应用程序的正确设计应该是什么.