@glaucidium

Возможно ли в C# отменить Ping?

Казалось бы есть метод SendAsyncCancel(). Однако пишем код

private Ping pinger = new Ping();

        private async void buttonPing_Click(object sender, EventArgs e)
        {
            try
            {
                PingReply reply = await pinger.SendPingAsync("66.99.66.99", 30000); //Ждём ответа 30 секунд
                textBox1.AppendText(reply.Status.ToString() + Environment.NewLine);
            }
            catch (Exception exception)
            {
                textBox1.AppendText("Сработал exception: " + exception.Message + Environment.NewLine);
            }
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            pinger.SendAsyncCancel();            
            textBox1.AppendText("Отмена" + Environment.NewLine);
        }

И при отмене форма виснет на все выставленные 30 секунд.
Ладно, меняем pinger.SendAsyncCancel(); на new Thread(pinger.SendAsyncCancel).Start();
И форма не виснет. Но сообщение «A task was canceled» всё равно появляется после истечения таймаута.
Почему пингующая задача не завершается сразу?
Может в c# имеются альтернативы Ping?
  • Вопрос задан
  • 412 просмотров
Решения вопроса 1
@glaucidium Автор вопроса
Нашёл решение. Прекрасно работает. На очистку ресурсов не проверял.
public Task<PingReply> SendPingAsync(string host, int timeout, CancellationToken cancelToken)
        {            
            TaskCompletionSource<PingReply> tcs = new TaskCompletionSource<PingReply>();
            if (cancelToken.IsCancellationRequested)         
                tcs.TrySetCanceled();
            else
            {
                using (Ping ping = new Ping())
                {
                    ping.PingCompleted += (object sender, PingCompletedEventArgs e) =>
                    {
                        if (!cancelToken.IsCancellationRequested)
                        {
                            if (e.Cancelled)                                
                                tcs.TrySetCanceled();
                            else if (e.Error != null)                                
                                tcs.TrySetException(e.Error);
                            else                                
                                tcs.TrySetResult(e.Reply);
                            }                        
                    };
                    cancelToken.Register(() => {tcs.TrySetCanceled();});

                    ping.SendAsync(host, timeout, null);
                }
            };
            return tcs.Task;
        }
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы