I'm currently working on a very cool (top secret) project with 3 Leaf, where I need to know when my application is online or offline. Sean told me to look into the System.Net.NetworkInformation namespace, and even got me hooked up with a solid example of using it that Arian had done for another up-and-coming project involving Tablet PC.
But I needed to expose the 'notification' to a couple of key areas in my class, so I figured I'd abstract all of the happy logic down into a single class that would make for even easier to reuse by providing encapsulation of the notifications as well as a good way to evaluate current status as needed.
First, you'll need an enum:
public enum ConnectionStatus
{
Unknown,
Connected,
Disconnected
}
Defaulting to Unknown is sensible enough - and hopefully you'll never stay there long. Once that's done, a simple delegate, that will be used for notifications/events:
public delegate void NetworkStatusChangedEventHandler(
object sender, NetworkStatusChangedEventArgs e);
Of course, in order for that event to work, we'll need a custom EventArgs class to match the signature of the event - and, logically, this class can send the new status along as part of the Event so that anything subscribing to the Event will be informed immediately of the new state:
public class NetworkStatusChangedEventArgs : EventArgs
{
private ConnectionStatus _state;
public ConnectionStatus ConnectionState
{
get { return _state; }
set { _state = value; }
}
public NetworkStatusChangedEventArgs(ConnectionStatus state)
{
this._state = state;
}
}
The class will effectively just wrap some of the key components of the namespace, and make them more easy to interact with. In addition to an Event that announces changes in the network status the class will expose a simple property that lets us interrogate it directly for the network connectivity status. So it effectively ends up looking, modelled, like so:

Under the covers, the only non-transparent bit of logic is the need for
synchronization locking, just in case the network adapter gets a bit flaky and doesn't know if it's online/offline. Otherwise it's a simple question of abstracting away an internally broadcast event, and exposing a simple property:
public class NetworkStatus
{
private object _syncLock = new object();
private NetworkAvailabilityChangedEventHandler networkChanged;
public event NetworkStatusChangedEventHandler NetworkStatusChanged;
private ConnectionStatus _status;
public ConnectionStatus ConnectivityStatus
{
get { return _status; }
set { _status = value; }
}
public NetworkStatus()
{
this.DetermineNetworkStatus();
networkChanged = new NetworkAvailabilityChangedEventHandler(
NetworkChange_NetworkAvailabilityChanged);
NetworkChange.NetworkAvailabilityChanged += networkChanged;
}
private void NetworkChange_NetworkAvailabilityChanged(
object sender, NetworkAvailabilityEventArgs e)
{
this.DetermineNetworkStatus();
}
private void DetermineNetworkStatus()
{
bool online = NetworkInterface.GetIsNetworkAvailable();
ConnectionStatus current =
online ? ConnectionStatus.Connected :
ConnectionStatus.Disconnected;
bool changed = false;
lock (this._syncLock)
{
if (this._status != current)
{
this._status = current;
changed = true;
}
}
if (changed)
{
NetworkStatusChangedEventArgs e =
new NetworkStatusChangedEventArgs(current);
this.OnChanged(e);
}
}
protected virtual void OnChanged(NetworkStatusChangedEventArgs e)
{
if (NetworkStatusChanged != null)
NetworkStatusChanged(this, e);
}
}
And voila! a simple to use NetworkStatus class. It can now be bound up as needed, for example, in the constructor of a class that will benefit from it:
private void ClassThatNeedsNetworkNotification_Load(
object sender, EventArgs e)
{
this._networkStatus = new NetworkStatus();
ConnectionStatus status = this._networkStatus.ConnectivityStatus;
this.BindConnectionStatus(status);
this._networkStatus.NetworkStatusChanged
+= new NetworkStatusChangedEventHandler(NetworkStatusChanged);
// other wire up as needed } private void NetworkStatusChanged(
object sender, NetworkStatusChangedEventArgs e)
{
this.DoSomethingWithNewState(e.ConnectionState);
}
It can also be passed in to other objects as part of their constructor and so on. (I suppose it could be fairly easily turned into a singleton too if you had the need...)




I have a quick question on this: In your method:
private void ClassThatNeedsNetworkNotification_Load(
object sender, EventArgs e)
{
this._networkStatus = new NetworkStatus();
ConnectionStatus status = this._networkStatus.ConnectivityStatus;
this.BindConnectionStatus(status);
this._networkStatus.NetworkStatusChanged
+= new NetworkStatusChangedEventHandler(NetworkStatusChanged);
// other wire up as needed
}
What/where is code the method for this.BindConnectionStatus(status);?? What does it do?
Thanks!
Posted by: Chad | November 17, 2005 at 09:04 AM
Chad,
That's just a super simple method that takes the status (an enum) and 'binds' it to the winform, or whatever else you've got that is consuming this class.
For example... say I was building a simple winform with a status bar. Upon loading the winform, the constructor would instantiate a new NetworkStatus class, grab the current status (connected or offline), and send that to the BindStatus(status) method. The BindStatus method could then either toggle icons, or display text such as: Online, or Offline so that the user would know their status (if they didn't already).
(i.e. it's really nothing).
Posted by: Michael K. Campbell | November 17, 2005 at 09:26 AM
Hi Michael,
first off all thanks a lot for providing this great NetworkStatus class. Unfortunatley, when using it in one of my projects I experienced that it was not working in some circumstances. After some research I found an explanation on MSDN. The NetworkAvailabilityChanged event uses also the static GetIsNetworkAvailable() method to determine the network status, but unfortunately this method returns true whenever one of the available network adapters is up and running and its type is not "loopback" or "tunnel". But this behavior will cause problems on machines with VMWare installed, because VMWare installs at least two additional NetworkAdapters that - unless they are deactivated - are always "Up", even if there is no "real" NetworkAdapter connected. Because I read that you are also a fan of VMWare I hope you have also noticed that problem and developed a solution already?! :-)
Regards, Bjoern
Posted by: Björn Waide | July 05, 2006 at 05:17 AM