#region Directives
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Threading;
using System.Windows;
#endregion Directives
namespace PingTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
#region Fields
// boolean used to exit the tracking thread
bool _isChecking = true;
// Stopwatch to monitor performance
Stopwatch sw = new Stopwatch();
#endregion Fields
#region Properties
// Thread safe synchronised collection... a lot faster than using lock(){}
private SynchronizedCollection<PingResult> ResultCollection
{
get
{
if (_ResultCollection == null)
{
_ResultCollection = new System.Collections.Generic.SynchronizedCollection<PingResult>();
}
return _ResultCollection;
}
set
{
_ResultCollection = value;
}
}
private SynchronizedCollection<PingResult> _ResultCollection;
#endregion Properties
#region Constructor Methods
public MainWindow()
{
InitializeComponent();
// Start spinning threads
PingAddresses();
// Start tracking progress
SpawnTrackingThread();
}
#endregion Constructor Methods
#region Methods
/// <summary> Method that spawns threads. It's not ideal to spawn this many threads... but as the threads spend most of their time waiting for a ping reply
/// as opposed to processing, it's not that bad. Also, for this situation, we won't go over 256 threads, so it can be justified in the interest of performance
/// </summary>
private void PingAddresses()
{
sw.Start();
for (int i = 0; i < 256; i++)
{
string ipAddress = string.Format("192.168.0.{0}", i);
System.Threading.Thread thread = new System.Threading.Thread(
new System.Threading.ThreadStart(
delegate()
{
Ping ping = new Ping();
PingOptions options = new PingOptions
{
DontFragment = true
};
byte[] buffer = new byte[32];
int timeout = 120;
try
{
PingReply reply = ping.Send(ipAddress, timeout, buffer, options);
bool result = reply.Status == IPStatus.Success;
PingResult pingResult = new PingResult(ipAddress, result);
ResultCollection.Add(pingResult);
}
catch
{
}
}
));
thread.Start();
}
}
private void SpawnTrackingThread()
{
Thread thread = new Thread(new ThreadStart(CheckingThread));
thread.IsBackground = true;
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
/// <summary> Use a tracking thread to monitor the progress of the main thread.
/// This way we do not need to check on every iteration which will slow the processing down considerably
/// </summary>
private void CheckingThread()
{
while (_isChecking == true)
{
if (_ResultCollection.Count == 254)
{
sw.Stop();
Application.Current.Dispatcher.BeginInvoke((Action)(() =>
{
// Dispatch the UI updates back onto the UI Thread
for (int i = 0; i < _ResultCollection.Count; i++)
{
Console.WriteLine("{0} {1}", _ResultCollection[i].IPAddress, _ResultCollection[i].Result);
}
Console.WriteLine("{0}", sw.Elapsed);
}));
_isChecking = false;
Thread.Sleep(50);
}
}
}
#endregion Methods
}
/// <summary> Result Container
/// </summary>
public class PingResult
{
#region Properties
public string IPAddress
{
get;
set;
}
public bool Result
{
get;
set;
}
#endregion Properties
#region Constructor Methods
public PingResult()
{
}
public PingResult(string ipAddress, bool result)
{
IPAddress = ipAddress;
Result = result;
}
#endregion Constructor Methods
}
}