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:
- Add the NetworkInformationUtility.cs to your project.
- Attach method to the event NetworkInformationUtility.GetNetworkTypeCompleted.
- Call NetworkInformationUtility.GetNetworkTypeAsync(3000 /*timeout in ms*/);
- 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
Gary Davis
May 13, 2012 @ 10:32:43
Links to the two downloads do not work (file://…). I will use the code in the blog.
Thanks for the info.
archiecoder
May 13, 2012 @ 11:09:17
Hi Gary,
Thank you for reporting this issue. I fixed the links.
ArchieCoder
PHenry
May 13, 2012 @ 12:45:18
VERY cool blog article! I wish MORE apps would check to see what or IF they have a network connection before doing something appropriately (like displaying cached data). IE I which more people would employ code like your’s! Keep it up!
archiecoder
May 13, 2012 @ 18:09:33
Thanks Peter 🙂
teoman
May 15, 2012 @ 01:00:49
very nice article, I was looking for this.
Thanks!
Mobile != NetworkConnected | .Netitude | .Net development with an edge
Jul 10, 2012 @ 00:39:16
[…] my good friend Sebastian over at DotNetApp.com suggested I combine my handy-dandy class w/ his NetworkInformationUtility class. “A splendid idea!” I said (right, Sebastian?) I took Sebastian’s code (will […]