san*_*p22 1 c# multithreading dictionary
我使用下面的代码启动带有列表参数的线程,但有时它会引发异常:
给定的密钥不在字典中
从这一行:
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[i]));
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个错误?
完整代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
您正在捕获变量 i,而不是其值.因此,目前您可以MoveTask使用相同的索引调用多个线程...有时候值i可能等于ControllerDictionary.Count.
如果你把一个副本的i进入循环内的变量,解决了这个问题,你会得到循环的每个迭代一个独立的变量:
for (int i = 0; i < ControllerDictionary.Count; i++)
{
int index = i;
Thread MoveThread = new Thread(() => MoveTask(ControllerDictionary[index]));
...
}
Run Code Online (Sandbox Code Playgroud)
或者甚至更好,ControllerDictionary完全从线程中提取fetch:
for (int i = 0; i < ControllerDictionary.Count; i++)
{
var value = ControllerDictionary[i];
Thread MoveThread = new Thread(() => MoveTask(value));
...
}
Run Code Online (Sandbox Code Playgroud)
另外,为什么你要使用字典还不是很清楚.鉴于您知道键将全部在范围内,[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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3003 次 |
| 最近记录: |