antman1p
antman1p

Reputation: 524

Program Locks up while pinging a subnet

I am new to programming. I created this GUI in C#/WPF and that pings a subnet that the user inputs. It works except that it freezes when I ping the entire 255 IP subnet. I would also like it to display the results as the value is returned in real time, but it waits to display the values until the entire subnet has been pinged. I'd also like some sort of progess bar. Can someone please take a look at my code and help me figure out what I need to do here? C# code below:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Net.Sockets;
    using System.Net.NetworkInformation;


    namespace PingTrueFalseSubnet  {

        public partial class Window1 : Window  {
            public Window1()  {
                InitializeComponent();
            }

            private void executeButton_Click(object sender, RoutedEventArgs e)  {
                string ipString;
                for (int i = 1; i < 100; i++)  {
                    ipString = inputTextBox.Text + "." + i;

                    //set the ping options, TTL 128
                    PingOptions pingOptions = new PingOptions(128, true);

                    //create a new ping instance
                    Ping ping = new Ping();

                    //32 byte buffer (create empty)
                    byte[] buffer = new byte[32];

                            try  {

                            //send the ping 4 times to the host and record the returned data.
                            //The Send() method expects 4 items:
                            //1) The IPAddress we are pinging
                            //2) The timeout value
                            //3) A buffer (our byte array)
                            //4) PingOptions

                            PingReply pingReply = ping.Send(ipString, 1000, buffer,   pingOptions);

                                //Make sure we don't have a null reply
                                if (!(pingReply == null))  {
                                    switch (pingReply.Status)  {
                                        case IPStatus.Success:
                                            outputTextBox.AppendText
                                                (string.Format("\nReply from {0}: bytes={1} time={2}ms TTL={3} Hostname={4}\n",
                                                pingReply.Address, pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Options.Ttl, 
                                                System.Net.Dns.GetHostEntry(ipString).HostName));
                                            break;
                                        case IPStatus.TimedOut:
                                            outputTextBox.AppendText(string.Format("\n{0} Connection has timed out...\n", ipString));
                                            break;
                                        default:
                                            outputTextBox.AppendText(string.Format("\n{0} Ping failed: {1}\n",ipString, 
                                                pingReply.Status.ToString()));
                                        break;
                                    }
                                }
                                else
                                    outputTextBox.AppendText(string.Format("\n{0} Connection failed for an unknown reason...\n", ipString));
                            }
                            catch (PingException ex)  {
                                outputTextBox.AppendText(string.Format("\n{0} Connection Error: {1}\n", ipString, ex.Message));
                            }
                            catch (SocketException ex) {
                                outputTextBox.AppendText(string.Format("\n{0} Connection Error: {1}\n", ipString, ex.Message));
                            }

                    }
                }

            private void button1_Click(object sender, RoutedEventArgs e)
            {
                outputTextBox.Clear();
            }
        }
    }

Below is the XAML markup:

    <Window x:Class="PingTrueFalseSubnet.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Ping True False Subnet" Height="376" Width="509" Name="pingMainWindow">
        <Grid>
            <TextBox Height="33" Margin="0,32,27,0" Name="inputTextBox" VerticalAlignment="Top" HorizontalAlignment="Right" 
                     Width="175"></TextBox>
            <Label Height="30" Margin="138,35,204,0" Name="inputLabel" VerticalAlignment="Top" FontSize="14" 
                   VerticalContentAlignment="Top">Enter subnet:</Label>
            <Label Height="28" Margin="60,108,0,0" Name="label1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="99">Results:</Label>
            <Button Height="27" Margin="150,77,162,0" Name="executeButton" VerticalAlignment="Top" Click="executeButton_Click">Execute</Button>
            <TextBox Margin="60,135,48,39" Name="outputTextBox" BorderBrush="Black" IsReadOnly="True" TextWrapping="Wrap" 
                     HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto" AcceptsReturn="True" />
            <Button Height="21" Margin="150,0,162,8" Name="clearButton" VerticalAlignment="Bottom" Click="button1_Click">Clear</Button>
            <ProgressBar Height="22" HorizontalAlignment="Right" Name="progressBar" VerticalAlignment="Bottom" Width="146" />
        </Grid>
    </Window>

Upvotes: 2

Views: 660

Answers (2)

antman1p
antman1p

Reputation: 524

Thanks to Itn's answer! The second link provided an example code for a DoWork() method that works perfectly.

http://dedjo.blogspot.com/2007/08/how-to-doevents-in-wpf.html

Add these two...

    using System.Threading;
    using System.Windows.Threading;

Call this method at the end of the for loop....

    DoWork();

Here is the example method from Itn's link...

    static void DoEvents()
    {
        DispatcherFrame frame = new DispatcherFrame(true);
        Dispatcher.CurrentDispatcher.BeginInvoke
        (DispatcherPriority.Background, (SendOrPostCallback) delegate(object arg)
        {
            var f = arg as DispatcherFrame; 
            f.Continue = false;
        }, 
        frame);
        Dispatcher.PushFrame(frame);
    } 

Upvotes: 0

Hamlet Hakobyan
Hamlet Hakobyan

Reputation: 33381

You can examine this post to see how to pnig asynchronously. This is just example not exact solution for your WPF application.

Upvotes: 2

Related Questions