首页 新闻 会员 周边 捐助

多线程获取局域网在线机器的疑问

0
悬赏园豆:200 [已解决问题] 解决于 2009-07-21 09:58

我用多线程获取指定IP段的可PING通的在线机器的IP地址,主要代码如下:

 

List<string> ipList = new List<string>();

private void FrmMain_Load(object sender, EventArgs e)
{
    Thread[] td = new Thread[51];
    Dictionary<string, int> dictionaryRangeValue = new Dictionary<string, int>();
    for (int i = 0; i <= 50; i++)
    {
        dictionaryRangeValue.Clear();
        dictionaryRangeValue.Add("rangeFrom", i * 5 + 1);
        dictionaryRangeValue.Add("rangeTo", (i + 1) * 5);
        td[i] = new Thread(new ParameterizedThreadStart(GetConnection));

        td[i].Start(dictionaryRangeValue);
    }

    for (int j = 0; j <= 50; j++)
    {
        td[j].Join();
    }
    MessageBox.Show(ipList.Count.ToString());
}

private void GetConnection(object dictionaryRangeValue)
{
    try
    {
 //获取当前在线的主机IP
 Connection connection = new Connection();
 string ipAddress = string.Empty;
 Dictionary<string, int> rv = dictionaryRangeValue as Dictionary<string, int>;
 for (int i = Convert.ToInt32(rv["rangeFrom"]); i <= Convert.ToInt32(rv["rangeTo"]); i++)
 {
         ipAddress = "192.168.125." + i.ToString();
         if (connection.test(ipAddress))
         {
         ipList.Add(ipAddress);
     }
 }
    }
    catch (Exception ex)
    {
 throw ex;
    }
}

 

其中Connection 为连接类,该类只负责连接IP,应该无问题

现在的问题是在执行时,有时在出现   “给定关键字不在字典中。”的异常
有时就算不出异常,在 MessageBox.Show(ipList.Count.ToString()); 得到的结果也不对
得到的结果是2000+,里面有很多重复的值

不明白错在什么地方,请各位高手帮忙解释修改一下,谢谢

神魔之刻的主页 神魔之刻 | 初学一级 | 园豆:2
提问于:2009-07-20 15:05
< >
分享
最佳答案
0

我觉得是这样一个情况,你将dictionaryRangeValue传递给线程,线程立即开始,然后再进入下一个循环,清理dictionaryRangeValu,再重新装入数据,问题就出在这里:

假如进入下一循环后清空了dictionaryRangeValue,

而这时前面的线程刚好执行到Dictionary<string, int> rv = dictionaryRangeValue as Dictionary<string, int>;

等于是拿来了一个空的Dictionary<string, int>,所以报错: “给定关键字不在字典中。”

数据重复问题也是源于这里,就是恰好在前面的线程读取Dictionary<string, int>之前将其清空,并填入了新的数据,这样前面的线程拿到的也是这次循环中的新数据,当然就会重复。

解决办法很简单,把Dictionary<string, int> dictionaryRangeValue = new Dictionary<string, int>();放进循环里去:

   
    for (int i = 0; i <= 50; i++)
    {
        Dictionary<string, int> dictionaryRangeValue = new Dictionary<string, int>();
        dictionaryRangeValue.Add("rangeFrom", i * 5 + 1);
        dictionaryRangeValue.Add("rangeTo", (i + 1) * 5);
        td[i] = new Thread(new ParameterizedThreadStart(GetConnection));

        td[i].Start(dictionaryRangeValue);
    }

斯克迪亚 | 老鸟四级 |园豆:4124 | 2009-07-20 17:23
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册