程序锁定在 ping 子网时

本文关键字:子网 ping 锁定 程序 | 更新日期: 2023-09-27 17:56:29

我是编程新手。 我在 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>

程序锁定在 ping 子网时

你可以检查这篇文章,看看如何异步pnig。这只是示例,不是您的WPF应用程序的确切解决方案。

感谢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);
    }