程序锁定在 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>
你可以检查这篇文章,看看如何异步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);
}