检查服务器Ping时冻结的UI

时间:2017-09-27 09:45:09

标签: c# winforms server ping

我想重复我的代码(循环),但我使用"转到"编译后我的程序没有响应! 如果添加另一个按钮For Stop 谢谢你的帮助...... 我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Diagnostics;
namespace SiteCheck
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        Start:
        Thread.Sleep(1000);
        string site = txtSite.Text;
        var ping = new System.Net.NetworkInformation.Ping();

        var result = ping.Send(site);

        if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
        {
            lblStatus.Text = "Down";
            goto Start;
        }
        else
        {
            lblStatus.Text = "Up";
            goto Start;                              
        }

    }          

}
}

enter image description here

2 个答案:

答案 0 :(得分:0)

您的程序没有响应,因为您正在阻止GUI线程。

这不能通过用循环替换goto(最好忘记它存在!)来解决。你仍然会阻止GUI线程。

您想在单独的线程上执行ping操作。或者 - 如果Async API可用 - 以异步方式执行。

这是一种使用ThreadPool和UI-Updates进展的方法。 假设您有一个“停止” - 按钮。

// For exiting the loop
private volatile bool _doPing = true;

private void btnStop_Click(object sender, EventArgs e )
{
    _doPing = false;
}

private void btnStart_Click(object sender, EventArgs e)
{
    _doPing = true;
    IProgress<bool> statusUpdate = new Progress<bool>( message =>
         lblStatus.Text = message ? "Up" : "Down"; // Will execute on UI Thread
    );

    // This will execute the Pinging on a ThreadPool Thread.
    Task.Run( () => DoPing( statusUpdate, txtSite.Text ));
}   

private void DoPing( IProgress<bool> status, string site )
{
     while( _doPing ) // Loop won't block your application
     {
         Thread.Sleep(1000);
         using(var ping = new System.Net.NetworkInformation.Ping())
         {
             var result = ping.Send(site);
             // UI-Update:
             status?.Report (result.Status == System.Net.NetworkInformation.IPStatus.Success);
         }
     }
}

这里还有很多可以改进的地方。我只是不想太夸大代码部分。第一步是/可能是异常处理。

使用SendPingAsync方法也可以实现完全基于任务的异步方法。

另一种方法是启用Component引发事件并注册PingCompleted事件。然后你可以使用Timer每秒发送一次ping。另请参阅SendAsync

答案 1 :(得分:0)

代码的编写方式一次只能做一件事,更新界面,睡觉或进行检查。

首先,您可能还希望查看计时器以触发检查而不是goto语句。您可以使用backgroundworker将检查任务传递给另一个线程。

请参阅what is the purpose of backgroundWorker ? (can i get some sample code to understand ?)