(有时)给定的键在字典中不存在
本文关键字:字典 不存在 有时 | 更新日期: 2023-09-27 18:14:26
我使用下面的代码来启动带有列表参数的线程,但有时会抛出异常:
给定的键在字典中不存在
从这行开始:
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[i]));
我如何修复这个错误?
完整代码:
var ControllerDictionary = ConfigFile.ControllerList.Select((c, i) => new { Controller = c, Index = i })
.GroupBy(x => x.Index % AppSettings.SimultaneousProcessNumber)
.Select((g, i) => new { GroupIndex = i, Group = g })
.ToDictionary(x => x.GroupIndex, x => x.Group.Select(xx => xx.Controller).ToList());
for (int i = 0; i < ControllerDictionary.Count; i++)
{
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[i]));
MoveThread.Start();
foreach (var Controller in ControllerDictionary[i])
Logger.Write(string.Format("{0} is in move thread {1}.", Controller.Ip, (i + 1)),EventLogEntryType.Information, AppSettings.LogInfoMessages);
}
您捕获的是变量 i
,而不是它的值。所以目前你可以有几个线程调用MoveTask
使用相同的索引…有时i
的值可能等于ControllerDictionary.Count
。
如果你把i
的复制到循环中的一个变量中,这就解决了这个问题,因为你会在每次循环的迭代中得到一个单独的变量:
for (int i = 0; i < ControllerDictionary.Count; i++)
{
int index = i;
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[index]));
...
}
或者更好的是,完全从线程中提取ControllerDictionary
取回:
for (int i = 0; i < ControllerDictionary.Count; i++)
{
var value = ControllerDictionary[i];
Thread MoveThread = new Thread(() => MoveTask(value));
...
}
此外,你根本不清楚为什么要使用字典。既然你知道键都在[0, count)
范围内,为什么不直接使用数组呢?您可以将查询更改为:
var controllerLists = ConfigFile.ControllerList
.Select((c, i) => new { Controller = c, Index = i })
.GroupBy(x => x.Index % AppSettings.SimultaneousProcessNumber)
.Select(g => g.Select(xx => xx.Controller).ToList())
.ToArray();
问题就在这里:
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[i]));
该匿名函数将在另一个线程上执行,并且不能保证局部变量是有效的