0

When I execute this code in command line, it's working fine:

class Program
{

    private static List<Ping> pingers = new List<Ping>();
    private static List<string> value = new List<string>();
    private static int instances = 0;
    private static object @lock = new object();
    private static int result = 0;
    private static int timeOut = 2500;
    private static int ttl = 7;
    public static void Main()
    {
        string baseIP = "192.168.1.";

        Console.WriteLine("Pinging  destinations of D-class in {0}*", baseIP);

        CreatePingers(254);


        PingOptions po = new PingOptions(ttl, true);
        System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
        byte[] data = enc.GetBytes("");

        SpinWait wait = new SpinWait();
        int cnt =1;

        Stopwatch watch = Stopwatch.StartNew();

        foreach (Ping p in pingers)
        {
            lock (@lock)
            {
                instances += 1;
            }

            p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeOut, data, po);
            cnt += 1;
        }

        //while (instances > 0)
        //{
        //    wait.SpinOnce();
        //}

        watch.Stop();
        for (int i = 0; i < value.Count; i++)
        {
            Console.WriteLine(value[i]);
        }
        DestroyPingers();

        Console.WriteLine("Finished in {0}. Found {1} active IP-addresses.", watch.Elapsed.ToString(), result);
        Console.ReadKey();

    }

    public static void Ping_completed(object s, PingCompletedEventArgs e)
    {
        lock (@lock)
        {
            instances -= 1;
        }

        if (e.Reply.Status == IPStatus.Success)
        {

           string sa = string.Concat("Active IP: ", e.Reply.Address.ToString());
           value.Add(sa);
          //Console.WriteLine(sa);
            String diachiip = e.Reply.Address.ToString();
            result += 1;

        }
        else
        {
            //Console.WriteLine(String.Concat("Non-active IP: ", e.Reply.Address.ToString()))
        }
    }


    private static void CreatePingers(int cnt)
    {
        for (int i = 1; i <= cnt; i++)
        {
            Ping p = new Ping();
            p.PingCompleted += Ping_completed;
            pingers.Add(p);
        }
    }

    private static void DestroyPingers()
    {
        foreach (Ping p in pingers)
        {
            p.PingCompleted -= Ping_completed;
            p.Dispose();
        }

        pingers.Clear();

    }
}

But when I convert from it to window form, it doesn't work. I don't kwow why, I have tried many different ways...

Code is here:

public partial class Form1 : Form
{

    public static List<Ping> pingers = new List<Ping>();
    public static List<string> value = new List<string>();
    public static int instances = 0;
    public static object @lock = new object();
    public static int result = 0;
    public int timeout = 2500;
    public static int ttl = 7;
    public Form1()
    {
        InitializeComponent();
    }

    public void btnscan_Click(object sender, EventArgs e)
    {
        string baseIP = "192.168.1.";
        //int kt = Int32.Parse(txtkt.Text);
        //int start = Int32.Parse(txtstart.Text);
        CreatePingers(254);
        PingOptions po = new PingOptions(ttl, true);
        System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
        byte[] data = enc.GetBytes("");
        int cnt = 1;
        Stopwatch watch = Stopwatch.StartNew();
        foreach (Ping p in pingers)
        {
            lock (@lock)
            {
                instances += 1;

            }
            p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeout, data, po);
            cnt += 1;        
        }
        watch.Stop();
        //Result alway return 0
        lst1.Items.Add(result.ToString());
        lst1.Items.Add(value.Count.ToString());
        for (int i = 0; i < value.Count; i++)
        {
            lst1.Items.Add(value[i]);
            lst1.Items.Add("\n");
        }
        DestroyPingers();
        string a = "Finished in " + watch.Elapsed.ToString() + ". Found " + result + " active IP-addresses.";
        lst1.Items.Add(a);
    }


    public static void CreatePingers(int kt)
    {
        for (int start = 1; start <= kt; start++)
        {
            // class System.Net.NetworkInformation.Ping
            Ping p = new Ping();
            p.PingCompleted += Ping_completed();
            pingers.Add(p);
        }
    }

     public static PingCompletedEventHandler Ping_completed()
    {
         PingCompletedEventHandler a = new PingCompletedEventHandler(abc);
         return a;
    }

    static void abc(object s, PingCompletedEventArgs e)
     {
         value.Add("abc");
         lock (@lock)
         {
             instances -= 1;
         }
         if (e.Reply.Status == IPStatus.Success)
         {
             string abcd = string.Concat("Active IP: ", e.Reply.Address.ToString());
             value.Add(abcd);
             result += 1;
         }
     }
     public static void DestroyPingers()
     {
         foreach (Ping p in pingers)
         {
             p.PingCompleted -= Ping_completed();
             p.Dispose();
         }
         pingers.Clear();
     }
}

What is wrong in this code?

David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
Kyle
  • 67
  • 2
  • 10
  • Try to be more specific. *"Not work"* - is too broad description of the problem. Does it compiles, runs, shows error? Typical problem when going from console to windows application is attempt to organize closed processing loop. You can do same in winforms by using Timer, BackgroundWorker or another (than used by UI) thread (Taks, Thread). – Sinatr Nov 24 '15 at 15:05
  • Code no error at compiles time and runtime but variable result alway return 0. It mean line :"p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeout, data, po);" not work? I can't debug into this line so i dont know what happen in this. – Kyle Nov 24 '15 at 15:11
  • Please add a [**minimal**,complete and verifiable example](http://stackoverflow.com/help/mcve). – Markus W Mahlberg Nov 24 '15 at 20:00

1 Answers1

0

Method SendAsync returns 0 because you are not waiting for it to complete. You are missing await and async (see msdn):

async void btnscan_Click(object sender, EventArgs e)
{
    ...
    await p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeout, data, 
    ...
}

SpinWait was making code to work in console application. In winforms you should not use SpinWait (nor Sleep) in UI thread. You can create another thread (e.g. by using Task) and then you can copy/paste code from console application 1-to-1. But then you will need to use Invoke each time when you want to access UI controls.

async/await is really better.. if it will work (I concluded that from method name, I've no idea what method does, nor how to use it).

Perhaps I miss one thing, if SendAsync returns value, then you can get it by (the requirement to mark method where you use await with async still):

var result = await p.SendAsync(...);
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • thank you, follow your help, i found something helpful here: http://stackoverflow.com/questions/14962969/how-can-i-use-async-to-increase-winforms-performance – Kyle Nov 24 '15 at 15:39