(有时)字典中没有给定的键

我使用下面的代码启动带有list参数的线程,但有时它会引发exception:

给定的密​​钥不在字典中

从这一行:

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  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)范围内[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])); 

该匿名函数将在不同的线程上执行,并且无法保证局部变量有效。