使用多线程进行PINGing

时间:2014-12-17 10:12:49

标签: c# multithreading sockets ping wlan

我使用线程(这里只有两个用于检查)来ping我连接网络上的前8个设备。

public void testThread1()
    {
        // executing in thread
        lstLocal.FullRowSelect = true;
        bool value;
        for (int i = 0; i <= 3; i++)
        {

            string ping_var = "192.168.1" + "." + i;
            value = Ping(ping_var, 4, 4);
            if (value == true)
            {
                ListViewItem items = new ListViewItem(ping_var.ToString());
                lstLocal.Items.Add(items);
            }


        }
        return;

    }

调用线程
     private void Form1_Load(object sender, EventArgs e)
      {
        lstLocal.Items.Clear();
        lstLocal.View = View.Details;
        ThreadStart threaddelegate1 = new ThreadStart(new Form1().testThread1);

        //Calls Ping() with the same prameters as Thread1 but for next 4 devices
        ThreadStart threaddelegate2 = new ThreadStart(new Form1().testThread2);


        Thread newthread = new Thread(threaddelegate1);
        newthread[0] = new Thread(threaddelegate1);
        newthread[1] = new Thread(threaddelegate2);
        foreach (Thread mythread in newthread)
          {
             newthread.Start();


         }
    }

前4个设备由thread1进行PING,最后4个由thread2进行PING。相同的函数Ping()在没有线程的情况下调用时对我有效,但会导致延迟(所以线程逼近)。

它是什么原因?我调试并发现线程没有执行,应用程序退出Form1_Load()

2 个答案:

答案 0 :(得分:1)

线程正在启​​动,但在退出Form.Load之前它们没有做任何工作。然后当他们工作时,你试图从非UI线程修改UI,这将在线程中抛出异常。

如果要修改UI,则必须与UI线程同步。这通常是使用Form.Invoke完成的。在您的代码中,如果您更改此内容:

            ListViewItem items = new ListViewItem(ping_var.ToString());
            lstLocal.Items.Add(items);

this.Invoke((MethodInvoker) delegate
{
    ListViewItem items = new ListViewItem(ping_var.ToString());
    lstLocal.Items.Add(items);
});

它应该适合你。有关详细信息,请参阅MethodInvokerInvoke

顺便说一下,你可能不需要两个线程。只有一个线程执行ping操作,它可能会正常工作。

答案 1 :(得分:1)

只需使用Ping类的固有异步方法之一,而不是仅仅坐在那里等待网络请求完成就创建线程。您的原始代码也尝试从非UI线程更新UI,因此您需要确保不要在异步版本中执行此操作。

await的使用使这很容易。除此之外,它会自动封送异步操作的延续,使其处于当前上下文中,在本例中是UI线程,因此您无需自己处理。

public async Task PingThings()
{
    // executing in thread
    lstLocal.FullRowSelect = true;
    var tasks = Enumerable.Range(0, 3)
        .Select(i => new Ping().SendPingAsync("192.168.1" + "." + i));
    var replies = await Task.WhenAll(tasks);
    foreach (var reply in replies.Where(reply => reply.Status == IPStatus.Success))
        lstLocal.Items.Add(new ListViewItem(reply.Address.ToString()));
}