Skip to content

Commit 8d4bb5f

Browse files
committed
Close #66 + Performance improved
1 parent c442aea commit 8d4bb5f

File tree

1 file changed

+52
-34
lines changed

1 file changed

+52
-34
lines changed

Source/NETworkManager/Models/Network/Traceroute.cs

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,18 @@ public void TraceAsync(IPAddress ipAddress, TracerouteOptions traceOptions, Canc
4444
Task.Run(() =>
4545
{
4646
byte[] buffer = new byte[traceOptions.Buffer];
47-
int maximumHops = traceOptions.MaximumHops;
4847

48+
int maximumHops = traceOptions.MaximumHops;
4949
bool maximumHopsReached = false;
5050

51+
int pingCount = 3;
52+
5153
// Get the ttl of the ip
5254
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
5355
{
5456
PingReply pingReply;
5557

56-
for (int i = 0; i < 3; i++)
58+
for (int i = 0; i < pingCount; i++)
5759
{
5860
pingReply = ping.Send(ipAddress, traceOptions.Timeout, buffer, new System.Net.NetworkInformation.PingOptions() { Ttl = 64, DontFragment = traceOptions.DontFragement });
5961

@@ -71,59 +73,75 @@ public void TraceAsync(IPAddress ipAddress, TracerouteOptions traceOptions, Canc
7173
}
7274
}
7375

76+
int threads = (pingCount * maximumHops);
77+
78+
// Modify the ThreadPool for better performance
79+
ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads);
80+
ThreadPool.SetMinThreads(workerThreads + threads, completionPortThreads + threads);
81+
7482
// Async check all hops
75-
Parallel.For(1, maximumHops + 1, new ParallelOptions() { CancellationToken = cancellationToken }, i =>
83+
try
7684
{
77-
List<Task<Tuple<PingReply, long>>> tasks = new List<Task<Tuple<PingReply, long>>>();
78-
79-
for (int y = 0; y < 3; y++)
85+
ParallelOptions parallelOptions = new ParallelOptions()
8086
{
81-
tasks.Add(Task.Run(() =>
82-
{
83-
Stopwatch stopwatch = new Stopwatch();
87+
CancellationToken = cancellationToken,
88+
MaxDegreeOfParallelism = threads
89+
};
8490

85-
PingReply pingReply;
91+
Parallel.For(1, maximumHops + 1, parallelOptions, i =>
92+
{
93+
List<Task<Tuple<PingReply, long>>> tasks = new List<Task<Tuple<PingReply, long>>>();
8694

87-
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
95+
for (int y = 0; y < 3; y++)
96+
{
97+
tasks.Add(Task.Run(() =>
8898
{
89-
stopwatch.Start();
99+
Stopwatch stopwatch = new Stopwatch();
90100

91-
pingReply = ping.Send(ipAddress, traceOptions.Timeout, buffer, new System.Net.NetworkInformation.PingOptions() { Ttl = i, DontFragment = traceOptions.DontFragement });
101+
PingReply pingReply;
92102

93-
stopwatch.Stop();
94-
}
103+
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
104+
{
105+
stopwatch.Start();
95106

96-
return Tuple.Create(pingReply, stopwatch.ElapsedMilliseconds);
97-
}));
98-
}
107+
pingReply = ping.Send(ipAddress, traceOptions.Timeout, buffer, new System.Net.NetworkInformation.PingOptions() { Ttl = i, DontFragment = traceOptions.DontFragement });
99108

100-
Task.WaitAll(tasks.ToArray());
109+
stopwatch.Stop();
110+
}
101111

102-
// Here is a good point to cancel (Don't resolve dns...)
103-
if (cancellationToken.IsCancellationRequested)
104-
return;
112+
return Tuple.Create(pingReply, stopwatch.ElapsedMilliseconds);
113+
}));
114+
}
105115

106-
IPAddress ipAddressHop = tasks.FirstOrDefault(x => x.Result.Item1 != null).Result.Item1.Address;
116+
Task.WaitAll(tasks.ToArray());
107117

108-
string hostname = string.Empty;
118+
IPAddress ipAddressHop = tasks.FirstOrDefault(x => x.Result.Item1 != null).Result.Item1.Address;
109119

110-
try
111-
{
112-
if (ipAddressHop != null)
113-
hostname = Dns.GetHostEntry(ipAddressHop).HostName;
114-
}
115-
catch (SocketException) { } // Couldn't resolve hostname
120+
string hostname = string.Empty;
116121

117-
OnHopReceived(new TracerouteHopReceivedArgs(i, tasks[0].Result.Item2, tasks[1].Result.Item2, tasks[2].Result.Item2, ipAddressHop, hostname, tasks[0].Result.Item1.Status, tasks[1].Result.Item1.Status, tasks[2].Result.Item1.Status));
118-
});
122+
try
123+
{
124+
if (ipAddressHop != null)
125+
hostname = Dns.GetHostEntry(ipAddressHop).HostName;
126+
}
127+
catch (SocketException) { } // Couldn't resolve hostname
119128

120-
if (cancellationToken.IsCancellationRequested)
129+
OnHopReceived(new TracerouteHopReceivedArgs(i, tasks[0].Result.Item2, tasks[1].Result.Item2, tasks[2].Result.Item2, ipAddressHop, hostname, tasks[0].Result.Item1.Status, tasks[1].Result.Item1.Status, tasks[2].Result.Item1.Status));
130+
});
131+
}
132+
catch (OperationCanceledException)
133+
{
121134
OnUserHasCanceled();
122-
else if (maximumHopsReached)
135+
return;
136+
}
137+
138+
if (maximumHopsReached)
123139
OnMaximumHopsReached(new MaximumHopsReachedArgs(traceOptions.MaximumHops));
124140
else
125141
OnTraceComplete();
126142

143+
// Reset the ThreadPool to default
144+
ThreadPool.SetMinThreads(workerThreads, completionPortThreads);
127145
}, cancellationToken);
128146
}
129147
#endregion

0 commit comments

Comments
 (0)