@@ -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