How to get the Internet connection type without blocking the UI

All Windows Phone applications that use Internet data should always check if there is a valid Internet connection. If there is no connection, a proper message should be displayed to the user. If your application relies on a specific server, don’t assume that Internet is not available if a call to the server returns an error, because the server might be down while the Internet is still available.

The proper way to check if you have an Internet connection (WIFI, Ethernet, or none) is calling the property:

NetworkInterface.NetworkInterfaceType

Unfortunately, even if it’s not obvious, calling this property on the UI thread can block the UI for many seconds. To avoid this problem, I created a NetworkInformationUtility class (the class and the sample project are available at the end of the post):

using System.Threading;
using Microsoft.Phone.Net.NetworkInformation;

namespace DotNetApp.Utilities
{
    public class NetworkTypeEventArgs {
        #region Constructor

        public NetworkTypeEventArgs(NetworkInterfaceType type, bool hasTimeout = false)
        {
            Type = type;
            HasTimeout = hasTimeout;
        }

        #endregion #region Properties

        public bool HasTimeout { get; private set; }

        public bool HasInternet
        {
            get { return Type != NetworkInterfaceType.None; }
        }

        public NetworkInterfaceType Type { get; private set; }

        #endregion }

    /// <summary> /// Static class to get the NetworkInterfaceType without blocking the UI thread. /// </summary> public static class NetworkInformationUtility {
        #region Fields

        private static bool _isGettingNetworkType;
        private static readonly object _synchronizationObject = new object();
        private static Timer _timer;

        #endregion #region Methods

        /// <summary> /// Get the NetworkInterfaceType asynchronously. /// </summary> /// <param name="timeoutInMs">Specifies the timeout in milliseconds.</param> public static void GetNetworkTypeAsync(int timeoutInMs)
        {
            lock (_synchronizationObject)
            {
                if (!_isGettingNetworkType)
                {
                    _isGettingNetworkType = true;

                    if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
                    {
                        Thread thread = new Thread(GetNetworkType) {IsBackground = true};
                        thread.Start(timeoutInMs);
                    }
                    else {
                        FireGetNetworkTypeCompleted(NetworkInterfaceType.None);
                    }
                }
            }
        }

        #endregion #region Delegates

        public delegate void NetworkTypeEventHandler(object sender, NetworkTypeEventArgs networkTypeEventArgs);

        #endregion #region Events

        public static event NetworkTypeEventHandler GetNetworkTypeCompleted;

        #endregion #region Event Handlers

        private static void OnTimerElapsed(object state)
        {
            FireGetNetworkTypeCompleted(NetworkInterfaceType.None, true);
        }

        #endregion #region Private Methods

        private static void GetNetworkType(object state)
        {
            _timer = new Timer(OnTimerElapsed, null, (int)state, 0);

            // This is a blocking call, this is why a thread is used to let the UI to be fluid NetworkInterfaceType type = NetworkInterface.NetworkInterfaceType;

            _timer.Dispose();
            _timer = null;

            FireGetNetworkTypeCompleted(type);
        }

        private static void FireGetNetworkTypeCompleted(NetworkInterfaceType type, bool hasTimeout = false)
        {
            lock (_synchronizationObject)
            {
                if (_isGettingNetworkType)
                {
                    _isGettingNetworkType = false;

                    NetworkTypeEventHandler networkTypeEventHandler = GetNetworkTypeCompleted;

                    if (networkTypeEventHandler != null)
                    {
                        networkTypeEventHandler(null, new NetworkTypeEventArgs(type, hasTimeout));
                    }
                }
            }
        }

        #endregion }
}

Here are the steps to use this class in your code:

  1. Add the NetworkInformationUtility.cs to your project.
  2. Attach method to the event NetworkInformationUtility.GetNetworkTypeCompleted.
  3. Call NetworkInformationUtility.GetNetworkTypeAsync(3000 /*timeout in ms*/);
  4. Retrieve the result on the GetNetworkTypeCompleted method that you attached to the event.

Code sample:

using System.Windows;
using DotNetApp.Utilities;

namespace NetworkInformationApp
{
    public partial class MainPage {
        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            NetworkInformationUtility.GetNetworkTypeCompleted += GetNetworkTypeCompleted;

            NetworkInformationUtility.GetNetworkTypeAsync(3000); // Timeout of 3 seconds }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);

            NetworkInformationUtility.GetNetworkTypeCompleted -= GetNetworkTypeCompleted;
        }

        private void GetNetworkTypeCompleted(object sender, NetworkTypeEventArgs networkTypeEventArgs)
        {
            string message;

            if (networkTypeEventArgs.HasTimeout)
            {
                message = "The timeout occurred";
            }
            else if (networkTypeEventArgs.HasInternet)
            {
                message = "The Internet connection type is: " + networkTypeEventArgs.Type.ToString();
            }
            else {
                message = "There is no Internet connection";
            }

            // Always dispatch on the UI thread Dispatcher.BeginInvoke(() => MessageBox.Show(message));
        }
    }
}

Download NetworkInformationUtility.cs
Download Sample project

Canadian Developer Connection and AlignIT applications

For the great Developer Movement promotion, I had an idea to create an application from the content of the Canadian Developer Connection blog by our beloved Microsoft evangelists of Canada. The content of the blog is helpful for all developers around the world using Microsoft technologies. With their permission, I created the Canadian Developer Connection application:

The 3 main features of the app are:

  • Read articles and watch saved videos while you are on the go (i.e. without an Internet connection).
  • Receive notifications for unread posts and news on Live Tile.
  • Pin your favourite evangelists in the Start menu for quick access.

For those who don’t know about the Developer Movement promotion, if you build quality apps, you can get a Kinect, a 1 TB external hard drive, a Windows Phone, a 500$ gift voucher and so on.

For an additional app for the Developer Movement promotion, I created the AlignIT application. This application is based from the content of the AlignIT website. AlignIT is the one-stop source for Canadian infrastructure and development managers. The application is built with the same framework as the Canadian Developer Connection application, so contains the same feature set.

Welcome to my new blog!

Hello,

It is with a warm welcome that I invite you to read my new blog.

The blog will be dedicated to Windows Phone development, but from time to time you may also see some Windows 8 articles. Windows Phone and Windows 8 share the amazing Metro style, and a lot of the code is the same.

In the two years since I started developing for the Windows Phone platform, many extraordinarily cool things have happened to me. If you keep reading my blog, you will discover what these cool events have been, and you will also learn some tricks that will help you be successful in developing your own Windows Phone apps.

As a side note, please be aware that my first language is French, and so any grammatical errors are unintentional. I will try to do my best. Errors in code, however, you can blame me for!

Through the platform of my blog, I would like to share my passion for Windows Phone development, and I hope I’ll be able to help the WP community create more wonderful applications.

Happy coding!

Sébastien, alias ArchieCoder