[英](Sometimes) The given key was not present in the dictionary
I am using the code below to start threads with a list parameter but sometimes it throws an exception: 我正在使用下面的代码以list参数启动线程,但有时会引发异常:
The given key was not present in the dictionary
给定的键在字典中不存在
From this line: 从这一行:
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[i]));
How can I fix that error? 我该如何解决该错误?
Full code: 完整代码:
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);
}
You're capturing the variable i
, rather than its value. 您正在捕获变量
i
,而不是其值。 So currently you could have several threads calling MoveTask
using the same index... and sometimes the value of i
could be equal to ControllerDictionary.Count
. 因此,当前您可能有多个线程使用相同的索引调用
MoveTask
...,有时i
的值可能等于ControllerDictionary.Count
。
If you take a copy of i
into a variable within the loop, that fixes the problem as you'll get a separate variable on each iteration of the loop: 如果将
i
的副本带入循环中的变量,则可以解决此问题,因为在循环的每次迭代中都会得到一个单独的变量:
for (int i = 0; i < ControllerDictionary.Count; i++)
{
int index = i;
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[index]));
...
}
Or even better, extract the ControllerDictionary
fetch from the thread entirely: 甚至更好的是,从线程中完全提取
ControllerDictionary
获取:
for (int i = 0; i < ControllerDictionary.Count; i++)
{
var value = ControllerDictionary[i];
Thread MoveThread = new Thread(() => MoveTask(value));
...
}
Additionally, it's not really clear why you're using a dictionary at all. 此外,还不清楚为什么要使用字典。 Given that you know the keys will all be in the range
[0, count)
why don't you just use an array? 既然您知道键都将在
[0, count)
范围内[0, count)
为什么不只使用数组呢? You'd change your query to: 您可以将查询更改为:
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();
The problem is here: 问题在这里:
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[i]));
That anonymous function is going to be executed on a different thread and there is no guarantee that the local variables are going to be valid. 该匿名函数将在不同的线程上执行,并且不能保证局部变量将是有效的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.