2

我是编程新手。我在 C#/WPF 中创建了这个 GUI,它会 ping 用户输入的子网。它可以工作,只是当我 ping 整个 255 IP 子网时它会冻结。我还希望它在实时返回值时显示结果,但它会等待显示值,直到整个子网都被 ping 通。我也想要某种进度条。有人可以看看我的代码并帮助我弄清楚我需要在这里做什么吗?C#代码如下:

    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();
            }
        }
    }

下面是 XAML 标记:

    <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>
4

2 回答 2

2

您可以查看这篇文章以了解如何进行pnig异步操作。这只是示例,不适合您的WPF应用程序。

于 2013-01-29T21:31:46.580 回答
0

感谢Itn的回答!第二个链接提供了一个完美运行的 DoWork() 方法的示例代码。

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

加上这两个...

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

在 for 循环结束时调用此方法....

    DoWork();

这是Itn链接中的示例方法...

    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);
    } 
于 2013-01-30T15:49:58.640 回答