5

I have a large list of IP addresses in a datatable and i have to ping them so quickly, I used this code :

public bool PingIP(string IP)
{
    bool result = false;
    try
    {                
        Ping ping = new Ping();
        PingReply pingReply = ping.Send(IP);
        if (pingReply.Status == IPStatus.Success)
            result = true;
    }
    catch
    {
        result = false;
    }
    return result;
}

then i call it in while loop :

private void CheckNetworkState()
{
    while (rowindexping > -1)
    {
        if (rowindexping == tbl_ClientInfo.Rows.Count)
        {
            rowindexping = -1;
            return;
        }

        string ip = tbl_ClientInfo.Rows[rowindexping]["clientip"].ToString();
        if (!PingIP(ip))
        {
           do something
        }
        rowindexping++;
        Thread.Sleep(100);
    }
}

Since i want to do this work at the background of my project i call the class in a thread:

threadping = new Thread(CheckNetworkState);            
threadping.IsBackground = true;
threadping.Start(); 

my problem is that it takes so many time and does not work at the background. i mean the system is busy till all ip addresses in tbl_clientinfo go through the ping class. i want that system check all rows since i'm working with other part of my project.

Did i do correctly?

Alex
  • 14,104
  • 11
  • 54
  • 77
maryam mohammadi
  • 694
  • 3
  • 14
  • 27
  • 4
    Ping is NOT going to be quick. Worst case, every single ping packet is ignored/dropped/lost and you have to wait for the timeout period on every ping attempt. To make this "fast" you'll need to fire off MULTIPLE pings at the same time. – Marc B Nov 06 '11 at 06:13
  • speed of ping is not % 100 from code, its up to communication and network – Mustafa Ekici Nov 06 '11 at 06:15
  • You could use a ServerToPing[] and create many threads working in parallel. Then you can use parallel libraries or something like a semaphore to run and rule threads... – Marco Nov 06 '11 at 06:16
  • 4
    I'd maybe look into using Ping.SendAsync() – Lee Gunn Nov 06 '11 at 06:18
  • BTW, sending your thread to sleep for 100ms isn't going to speed it up! :) – Lee Gunn Nov 06 '11 at 06:20
  • 1
    https://stackoverflow.com/questions/13911473/multithreading-c-sharp-gui-ping-example – I4V Aug 22 '17 at 20:14

4 Answers4

3

Your code is running all the code on a single thread; you're not using multiple threads. Also, why do you have a Thread.Sleep in there?

Try the following:

  1. Query the database and get all the IPs
  2. In a loop, spin up a new thread that will run PingIP for each IP address

Note: You can also spin up a new thread every time you get a new row from the database

Sample:

    static void Main(string[] args)
    {
        // get the IPs from the database so you can iterate over them
        List<string> ips = new List<string>()
        {
            "google.com",
            "127.0.0.1",
            "stackoverflow.com"
        };

        foreach (var ip in ips)
        {
            // See http://stackoverflow.com/questions/4744630/unexpected-behaviour-for-threadpool-queueuserworkitem
            // for reason to use another variable in the loop
            string loopIp = ip;
            WaitCallback func = delegate(object state)
            {
                if (PingIP(loopIp))
                {
                    Console.WriteLine("Ping Success");
                }
                else
                {
                    Console.WriteLine("Ping Failed");
                }
            };
            ThreadPool.QueueUserWorkItem(func);
        }

        Console.ReadLine();
    }

    public static bool PingIP(string IP)
    {
        bool result = false;
        try
        {
            Ping ping = new Ping();
            PingReply pingReply = ping.Send(IP);

            if (pingReply.Status == IPStatus.Success)
                result = true;
        }
        catch
        {
            result = false;
        }

        return result;
    }
Omar
  • 39,496
  • 45
  • 145
  • 213
  • Thanx for u'r reply. but my problem is still on. why my thread does not work at background. the whole project is down till the list finish pinging!! sholdn't it work when thread is doing its job? – maryam mohammadi Nov 06 '11 at 07:45
  • @maryammohammadi - what do you mean the project is down? Looking at my example, you should be able to run whatever code you want AFTER the foreach loop and the pinging will still happen on different threads. – Omar Nov 06 '11 at 14:48
  • @Omar, how can I update each `label.Text`? I have a list of IP addresses on UI. – Badiparmagi Dec 22 '17 at 08:24
  • Put the code to update the label text in the same function that does the ping and update the label when the response comes back. – Omar Dec 22 '17 at 23:25
0

What I would do is have a separate multi-threaded daemon running in the background, doing the pings, and putting the results in a database. Have a page that loads results via AJAX later.

Brad
  • 159,648
  • 54
  • 349
  • 530
0

Consider making a system call to the fping utility. Granted, it's not managed code, but fping is very well optimized for your specific task and would simplify your problem down to a single call followed by the processing of a text-based list of results.

phatfingers
  • 9,770
  • 3
  • 30
  • 44
-1

you can use powershell

private string resultat(string s)
{
    Runspace space = RunspaceFactory.CreateRunspace();
    space.Open();

    Pipeline pipeline = space.CreatePipeline();
    pipeline.Commands.AddScript(s);
    pipeline.Commands.Add("Out-String");
    Collection<PSObject> results = pipeline.Invoke();

    StringBuilder stringBuilder = new StringBuilder();
    foreach (PSObject obj in results)
    {
        stringBuilder.AppendLine(obj.ToString());
    }

    return stringBuilder.ToString();
}

and then use resultat("ping -l 10 -n 2 " + your_ip);

mike_m
  • 1,526
  • 4
  • 14
  • 19
user3218923
  • 197
  • 1
  • 2
  • Why not call `ping.exe` directly instead of going through PowerShell? However you might call `ping.exe` you then have the additional step, compared to using the `Ping` class, of parsing the output so you know what the result was, which this code doesn't bother to do. This doesn't address the problem of IPs being pinged one at a time, anyways. -1 – Lance U. Matthews Aug 10 '19 at 17:50