C# Ping.Send 导致 GUI 冻结
C# Ping.Send causing GUI to freeze
第一次使用 Whosebug,所以我会尽力而为。
我正在制作一个小应用程序来 ping 一些服务器,我遇到的问题是程序的 GUI 在等待响应时被锁定。
这是我到目前为止所拥有的,Button_Click 是 "Ping IP" 按钮,ping_box 是一个包含响应时间的文本框,ip_address 是一个 IP 地址,形式为一个字符串。
private void Button_Click(object sender, RoutedEventArgs e)
{
Stopwatch s = new Stopwatch();
s.Start();
while (s.Elapsed < TimeSpan.FromSeconds(2))
{
using (Ping p = new Ping())
{
ping_box.Text = (p.Send(ip_address, 1000).RoundtripTime.ToString() + "ms\n");
if (ping_box.Text == "0ms\n")
{
ping_box.Text = "Server is offline or exceeds 1000ms.";
}
}
}
s.Stop();
}
因此在当前状态下,它会重复 ping IP 地址两秒钟,并将响应时间放入文本框,但在此期间 GUI 会锁定。
我需要重新更正此问题,因为我希望响应时间的文本框随每次 ping 更新(如果响应时间为 500 毫秒,则文本框应更新四次)。
我已经尝试使用 Ping.SendAsync 但无法正常工作,任何指点或帮助将不胜感激:)
Ping
Allows an application to determine whether a remote computer is
accessible over the network.
当您调用 Ping 时,您的主线程(也就是您的 UI 线程)已暂停并等待 ping 响应,这就是您的应用程序冻结的原因。
解决方法:
您需要将 Ping 放在另一个线程中
我认为这应该有所帮助...
您可以根据需要进一步修改它
private void button1_Click(object sender, EventArgs e)
{
AutoResetEvent waiter = new AutoResetEvent(false);
IPAddress ip = IPAddress.Parse("192.168.1.2");
var pingSender = new Ping();
pingSender.PingCompleted += PingCompletedCallback;
pingSender.SendAsync(ip, 1000, waiter);
}
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
// If an error occurred, display the exception to the user.
if (e.Error != null)
{
MessageBox.Show(string.Format("Ping failed: {0}", e.Error.ToString()),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
DisplayReply(e.Reply);
// Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
public void DisplayReply(PingReply reply)
{
if (reply == null)
return;
ping_box.Text = string.Format("Ping status: {0}, RoundTrip time: {1}",
reply.Status,
reply.RoundtripTime.ToString());
}
第一次使用 Whosebug,所以我会尽力而为。
我正在制作一个小应用程序来 ping 一些服务器,我遇到的问题是程序的 GUI 在等待响应时被锁定。 这是我到目前为止所拥有的,Button_Click 是 "Ping IP" 按钮,ping_box 是一个包含响应时间的文本框,ip_address 是一个 IP 地址,形式为一个字符串。
private void Button_Click(object sender, RoutedEventArgs e)
{
Stopwatch s = new Stopwatch();
s.Start();
while (s.Elapsed < TimeSpan.FromSeconds(2))
{
using (Ping p = new Ping())
{
ping_box.Text = (p.Send(ip_address, 1000).RoundtripTime.ToString() + "ms\n");
if (ping_box.Text == "0ms\n")
{
ping_box.Text = "Server is offline or exceeds 1000ms.";
}
}
}
s.Stop();
}
因此在当前状态下,它会重复 ping IP 地址两秒钟,并将响应时间放入文本框,但在此期间 GUI 会锁定。 我需要重新更正此问题,因为我希望响应时间的文本框随每次 ping 更新(如果响应时间为 500 毫秒,则文本框应更新四次)。
我已经尝试使用 Ping.SendAsync 但无法正常工作,任何指点或帮助将不胜感激:)
Ping
Allows an application to determine whether a remote computer is accessible over the network.
当您调用 Ping 时,您的主线程(也就是您的 UI 线程)已暂停并等待 ping 响应,这就是您的应用程序冻结的原因。
解决方法: 您需要将 Ping 放在另一个线程中
我认为这应该有所帮助... 您可以根据需要进一步修改它
private void button1_Click(object sender, EventArgs e)
{
AutoResetEvent waiter = new AutoResetEvent(false);
IPAddress ip = IPAddress.Parse("192.168.1.2");
var pingSender = new Ping();
pingSender.PingCompleted += PingCompletedCallback;
pingSender.SendAsync(ip, 1000, waiter);
}
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
// If an error occurred, display the exception to the user.
if (e.Error != null)
{
MessageBox.Show(string.Format("Ping failed: {0}", e.Error.ToString()),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
DisplayReply(e.Reply);
// Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
public void DisplayReply(PingReply reply)
{
if (reply == null)
return;
ping_box.Text = string.Format("Ping status: {0}, RoundTrip time: {1}",
reply.Status,
reply.RoundtripTime.ToString());
}