G
G
glaucidium2016-11-05 16:56:21
Ping
glaucidium, 2016-11-05 16:56:21

Is it possible in C# to cancel a Ping?

It would seem that there is a SendAsyncCancel() method. However, we write code

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

And when canceled, the form hangs for all the set 30 seconds.
Okay, change pinger.SendAsyncCancel(); on new Thread(pinger.SendAsyncCancel).Start();
And the form does not hang. But the message "A task was canceled" still appears after the timeout has expired.
Why doesn't the ping task complete immediately?
Maybe there are alternatives to Ping in c#?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
glaucidium, 2016-11-05
@glaucidium

Found a solution. Works great. I did not check for resource cleanup.

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;
        }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question