【发布时间】:2020-04-20 18:51:38
【问题描述】:
我的代码就是这样。
List<MyPanel> list_panel = new List<MyPanel>();
.......
List<string> list_sql = new List<string>();
Parallel.For(0, list_panel.Count, i =>
{
if (list_panel[i].R == 0)
{
list_sql.AddRange(list_panel[i].MakeSqlForSave()); // it returns two string
}
});
但 AddRange 有时会发生 System.ArgumentException。
我发现“列表不适用于多写”。所以我用锁来修复它。
string[] listLock = new string[2];
Parallel.For(0, list_panel.Count, i =>
{
if (list_panel[i].R == 0)
{
listLock = list_panel[i].MakeSqlForSave();
lock(listLock)
list_sql.AddRange(listLock);
}
});
但仍然会出现 System.ArgumentException '源数组不够长。检查 srcIndex 和长度,以及数组的下限。有时。
list_sql 中发生错误。如果计数为 34,但调用 list_sql[32] 和 list_sql[33] 时发生 IndexOfRangeException。
我该如何处理?
【问题讨论】:
-
List<T>(尤其是List<T>.AddRange)不是线程安全的。 -
您的
lock()语句不正确,因为它锁定了线程本地对象而不是共享对象。 -
MyPanel是 WinForms 控件吗?如果是这样,此代码是不安全的,因为 WinForms 控件只能从 GUI 线程访问。 -
您重新分配 listlock,然后锁定它。这使锁变得毫无意义,因为您将拥有许多锁。您不会锁定变量,而是锁定它所引用的(新)对象。
标签: c# list for-loop parallel-processing