简体   繁体   English

(有时)词典中不存在给定的键

[英](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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM