C# Ping.Send вызывает зависание GUI

В первый раз, используя Stackru, поэтому я постараюсь сделать все возможное.

Я делал небольшое приложение для проверки связи с некоторыми серверами, у меня проблема в том, что графический интерфейс программы блокируется, пока она ждет ответа. Это то, что у меня есть, 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();
    }

Таким образом, в своем текущем состоянии он повторно проверяет IP-адрес в течение двух секунд и помещает время ответа в текстовое поле, хотя в это время графический интерфейс блокируется. Мне нужно исправить это, так как я хочу, чтобы текстовое поле с временем отклика обновлялось с каждым пингом (если время отклика составляет 500 мс, тогда текстовое поле должно обновляться четыре раза).

Я пытался использовать Ping.SendAsync, но не смог заставить его работать, любые указатели или помощь будет высоко ценится:)

2 ответа

Решение

Я думаю, что это должно помочь... Вы можете изменить его в соответствии с вашими потребностями

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

}

пинг
Позволяет приложению определять, доступен ли удаленный компьютер по сети.

Когда вы вызывали Ping, ваш основной поток (а это ваш поток пользовательского интерфейса) был остановлен и ждал ответа от ping, поэтому ваше приложение зависло.

Решение: Вам нужно поместить Ping в другой поток

Другие вопросы по тегам