@@ -93,50 +93,36 @@ public static bool IsErrored(this IProcessProxy process, IEnumerable<int> succes
9393 /// </summary>
9494 /// <param name="process">The process to kill.</param>
9595 /// <param name="logger">The logger to use to write trace information.</param>
96- /// <param name="timeout ">Max duration to wait for exit, default to 3 minutes .</param>
97- public static void SafeKill ( this IProcessProxy process , ILogger logger = null , TimeSpan timeout = default )
96+ /// <param name="confirmationWaitTime ">Max duration to wait for exit. Default = 10 seconds. Use TimeSpan.Zero for no wait .</param>
97+ public static void SafeKill ( this IProcessProxy process , ILogger logger = null , TimeSpan ? confirmationWaitTime = null )
9898 {
99- TimeSpan effectiveTimeout = timeout == default ? TimeSpan . FromMinutes ( 3 ) : timeout ;
100- DateTime exitTime = DateTime . UtcNow . Add ( effectiveTimeout ) ;
101- List < Exception > errors = new List < Exception > ( ) ;
99+ TimeSpan effectiveTimeout = confirmationWaitTime ?? TimeSpan . FromSeconds ( 10 ) ;
102100
103- using ( CancellationTokenSource tokenSource = new CancellationTokenSource ( effectiveTimeout ) )
101+ if ( ! process . HasExited )
104102 {
105- while ( DateTime . UtcNow < exitTime )
103+ // Process confirmed exited
104+ try
106105 {
107- if ( process . HasExited )
108- {
109- // Process confirmed exited
110- break ;
111- }
106+ process . Kill ( true ) ;
112107
113- try
114- {
115- process . Kill ( true ) ;
116- process . WaitForExitAsync ( tokenSource . Token ) . GetAwaiter ( ) . GetResult ( ) ;
117- }
118- catch ( Exception exc )
108+ if ( confirmationWaitTime != TimeSpan . Zero )
119109 {
120- errors . Add ( exc ) ;
110+ process . WaitForExitAsync ( CancellationToken . None , confirmationWaitTime ) . GetAwaiter ( ) . GetResult ( ) ;
121111 }
122112 }
123- }
124-
125- if ( ! process . HasExited )
126- {
127- string processName = SafeGet < string > ( ( ) => process . Name ) ;
128- int processId = SafeGet < int > ( ( ) => process . Id ) ;
129-
130- EventContext errorContext = EventContext . Persisted ( ) ;
131- errorContext . AddProcessDetails ( process . ToProcessDetails ( process . Name ) ) ;
132- if ( errors . Any ( ) )
113+ catch ( Exception exc )
133114 {
134- errorContext . AddError ( new AggregateException (
115+ string processName = SafeGet < string > ( ( ) => process . Name ) ;
116+ int processId = SafeGet < int > ( ( ) => process . Id ) ;
117+
118+ EventContext errorContext = EventContext . Persisted ( ) ;
119+ errorContext . AddProcessDetails ( process . ToProcessDetails ( process . Name ) ) ;
120+ errorContext . AddError ( new WorkloadException (
135121 $ "Process kill attempt failed (id={ processId } , name={ processName } , timeout={ effectiveTimeout } ).",
136- errors ) ) ;
137- }
122+ exc ) ) ;
138123
139- logger ? . LogMessage ( $ "ProcessKillFailed.{ processName } ", LogLevel . Warning , errorContext ) ;
124+ logger ? . LogMessage ( $ "ProcessKillFailed.{ processName } ", LogLevel . Warning , errorContext ) ;
125+ }
140126 }
141127 }
142128
@@ -181,11 +167,11 @@ public static void SafeKill(this ProcessManager processManager, IEnumerable<stri
181167 /// </summary>
182168 /// <param name="processManager">Provides functionality for creating processes.</param>
183169 /// <param name="process">The process to kill.</param>
184- /// <param name="timeout">Max duration to wait for exit, default to 3 minutes.</param>
185170 /// <param name="logger">The logger to use to write trace information.</param>
186- public static void SafeKill ( this ProcessManager processManager , IProcessProxy process , ILogger logger = null , TimeSpan timeout = default )
171+ /// <param name="confirmationWaitTime">Max duration to wait for exit. Default = 10 seconds. Use TimeSpan.Zero for no wait.</param>
172+ public static void SafeKill ( this ProcessManager processManager , IProcessProxy process , ILogger logger = null , TimeSpan ? confirmationWaitTime = null )
187173 {
188- TimeSpan effectiveTimeout = timeout == default ? TimeSpan . FromMinutes ( 3 ) : timeout ;
174+ TimeSpan effectiveTimeout = confirmationWaitTime ?? TimeSpan . FromSeconds ( 10 ) ;
189175
190176 using ( CancellationTokenSource tokenSource = new CancellationTokenSource ( effectiveTimeout ) )
191177 {
@@ -201,7 +187,7 @@ public static void SafeKill(this ProcessManager processManager, IProcessProxy pr
201187 {
202188 using ( IProcessProxy kill = processManager . CreateProcess ( "kill" , $ "-9 { processId } ") )
203189 {
204- kill . StartAndWaitAsync ( tokenSource . Token , timeout )
190+ kill . StartAndWaitAsync ( tokenSource . Token , confirmationWaitTime )
205191 . GetAwaiter ( ) . GetResult ( ) ;
206192
207193 // 0 = Success
@@ -219,7 +205,7 @@ public static void SafeKill(this ProcessManager processManager, IProcessProxy pr
219205 {
220206 using ( IProcessProxy taskkill = processManager . CreateProcess ( "taskkill" , $ "/F /PID { processId } ") )
221207 {
222- taskkill . StartAndWaitAsync ( tokenSource . Token , timeout )
208+ taskkill . StartAndWaitAsync ( tokenSource . Token , confirmationWaitTime )
223209 . GetAwaiter ( ) . GetResult ( ) ;
224210
225211 // 0 = Success
0 commit comments