Click here to Skip to main content
13,252,815 members (50,188 online)
Click here to Skip to main content
Add your own
alternative version


34 bookmarked
Posted 22 Oct 2012

Continuous asynchronous Ping using TAP and IProgress in C#5

, 15 Jan 2014
Rate this:
Please Sign up or sign in to vote.
This article shows how to use C# 5 async functions to create a continuous asynchronous ping and report progress to the UI.


The new support for asynchronous functions in C# and Vb.Net 5.0 allow an efficient way to deal with concurrent operations represented as Task<TResult>. The big advantages in daily use are composability and automatic marshaling to the synchronization context (i.e. main thread). The latter saves a lot of calls to Dispatcher.BeginInvoke and their likes and makes the application virtually single threaded and by that easy to debug and maintain.

We can not only utilize these tools for short asynchronous tasks, but also for potentially endless ones. In this article I will use the TAP infrastructure to create an asynchronous Ping tool.

The TAP and IProgress

First of all we will have a look at our tools. If you are already familiar with Async Functions and the TAP you might want to skip this paragraph.

The new Async Functions in .Net consist of two parts. One is the extension of the compiler. This is surfaced by the introduction of two new keywords: async and await (resp. Async and Await in VB.Net). The usage of those is beyond the scope of this article, but Joseph Albahari’s talk gives a good introduction to those.

The other part is the Taskbased Asynchronous Pattern or TAP. The TAP defines the interface that asynchronous functions should implement. This paper of Stephen Toub describes the pattern in detail.

It states, that an asynchronous function should supply the following signature

Task<TResult> DoWorkAsync(&hellip; parameters, CancellationToken cancellationToken, IProgress<T> progress) 

The following points should be noted:

  • The method returns a Task
  • 'Async' is appended to the methods name
  • The method accepts a CancellationToken
  • The method accepts an IProgress<T>

For our task to create a continuous ping operation we are interested in the last two items.

We might need the ability to cancel the task at some time, so we will want to pass a CancellationToken. Furthermore we need a way to continuously report ping times. We achieve this by using IProgress<T>.

IProgress<T> and Progress<T>

As we saw, the .Net Framework 4.5, which is shipped with C# 5, provides an interface IProgress<T>. This interface contains one single method.

public interface IProgress<in T>
    void Report(T value);

As the name suggests, the asynchronous method can use that method to report progress.

The Framework also includes a simple implementation of that interface named Progress<T>. This class offers a constructor that accepts an Action<T> and an event ProgressChanged. Both can be used to register a callback for process updates. The Progress class invokes both the action and the event on the synchronization context, if one is present. Such a context is created automatically for every WPF, Silverlight and Forms application. That means that we do not have to care about form.Invoke resp. Dispatcher.BeginInvoke ourselves to update UI elements.

Asynchronous Ping using Progress<T>

Using all that, we can finally start to write our async ping.


First we need a class to report the progress of our Ping. That class is a container for miscellaneous information of the pings state.

public class PingResult
    public IPAddress Address { get; private set; }
    public int PingsTotal { get; private set; }
    public int PingsSuccessfull { get; private set; }
    public TimeSpan AverageTime { get; private set; }
    public TimeSpan LastTime { get; private set; }
    public IPStatus LastStatus { get; private set; }
    public PingResult(IPAddress address)
        Address = address;
        LastStatus = IPStatus.Unknown;
    internal void AddResult(PingReply res){ ... }

The AddResult method will be called by the ping method to accumulate the information into AverageTime, PingsTotal and so on. It accepts an instance of System.Net.NetworkInformation.PingReply.

The Ping methods

With that in place we can at last create the method I keep talking about since the beginning. The method is a thin wrapper around the functionality provided by System.Net.NetworkInformation.Ping.

public static async Task ContinuousPingAsync(
    IPAddress address, 
    int timeout, 
    int delayBetweenPings, 
    IProgress<PingResult> progress, 
    CancellationToken cancellationToken)
    var ping = new System.Net.NetworkInformation.Ping();
    var result = new PingResult(address);
    while (!cancellationToken.IsCancellationRequested)
        var res = await ping.SendPingAsync(address, timeout).ConfigureAwait(false);
        await Task.Delay(delayBetweenPings).ConfigureAwait(false);

That's all. If you think about the old days of APM with its BeginPing(...) and EndPing(IAsyncResult result) you might be surprised how simple it is to compose asynchronous methods. But let's get through that step by step.

I decided to define that method as static, since all states (result and ping) are hidden inside. As explained above, the method returns a Task to give the caller a handle to the running computation. That makes exception handling easy for the caller. An IProgress<PingResult> object is used to report the ping status. The method can be aborted using the CancellationToken.

Two async functions are invoked and awaited for within the while loop. Since no code is invoked from this loop that can potentially access UI elements, we use .ConfigureAwait(false) to signal the compiler that it does not have to continue on the captured synchronization context (i.e. the UI thread). All reporting us done using the Progress class, which takes care of the marshaling to the UI thread.

WPF Sample application

The source code also includes a simple WPF MVVM app demo application.

screenshot of WPF demo application

You can enter addresses of computers you want to ping. DNS resolution and ping are done asynchronously using this article's methods.

Using the code

The main library contains one static class with three methods to bring asynchronous ping functionality.

namespace Network
    public static class Ping
        public static IPAddress ResolveAddress(string hostNameOrAddress)
        public static async Task<IPAddress> ResolveAddressAsync(string hostNameOrAddress) 
        public static async Task ContinuousPingAsync(
            IPAddress address, 
            int timeout, 
            int delayBetweenPings, 
            IProgress<PingResult> progress, 
            CancellationToken cancellationToken) 

ResolveAddress and ResolveAddressAsync mimic the behaviour of System.Net.NetworkInformation.Ping for address resolution. In short you can provide an IP address as string or a hostname that will be resolved using DNS.

ContinuousPingAsync is used to start the continuous ping I keep talking about.

The interface is fairly simple. Please see the included WPF demo application for details. If you have any problems, feel free to contact me. 


  • 2012-10-21: Initial version 
  • 2012-10-25: Added source code 
  • 2014-01-15: Fixed code listing 


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Peter Butzhammer
Software Developer evopro systems engineering AG
Germany Germany
Peter Butzhammer studied physics but decided to work as a software developer 10 years ago. He has a strong interest in statistics, simulation and functional programming.

You may also be interested in...


Comments and Discussions

QuestionQuestion Re object passed to the report method Pin
dr_bob518819-Dec-15 16:41
memberdr_bob518819-Dec-15 16:41 
QuestionMy vote 5 /Cancel all pings and remove all task with one click Pin
SasaMiric4-Dec-15 7:55
memberSasaMiric4-Dec-15 7:55 
GeneralMy vote of 5 Pin
Member 1071845113-Jan-15 5:41
memberMember 1071845113-Jan-15 5:41 
Questionrepeated code: why? Pin
Adel Khalil22-Aug-14 8:20
memberAdel Khalil22-Aug-14 8:20 
QuestionContinuous asynchronous ping in c# winform Pin
FX Andy Widjaja30-May-14 22:01
memberFX Andy Widjaja30-May-14 22:01 
QuestionTask.Delay Pin
Emile van Gerwen15-Jan-14 3:42
memberEmile van Gerwen15-Jan-14 3:42 
AnswerRe: Task.Delay Pin
Peter Butzhammer15-Jan-14 10:40
memberPeter Butzhammer15-Jan-14 10:40 
GeneralMy vote of 5 Pin
Florian Rappl19-Dec-12 10:11
memberFlorian Rappl19-Dec-12 10:11 
Hey Peter, really nice article there! I enjoyed reading it and liked the provided example. Really good use of async methods and the IProgress interface!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171114.1 | Last Updated 15 Jan 2014
Article Copyright 2012 by Peter Butzhammer
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid