55
66namespace FFmpeg . NET . Extensions
77{
8- public static class ProcessExtensions
9- {
10- public static Task < int > WaitForExitAsync ( this Process process , bool stdInDataInput , Action < int > onException , CancellationToken cancellationToken = default )
11- {
12- CancellationTokenRegistration ctRegistration = new CancellationTokenRegistration ( ) ;
13- bool mustUnregister = false ;
14- TaskCompletionSource < int > tcs = new TaskCompletionSource < int > ( ) ;
15- if ( cancellationToken != default )
16- {
17- mustUnregister = true ;
18- ctRegistration = cancellationToken . Register ( ( ) =>
19- {
20- try
21- {
22- if ( stdInDataInput )
23- {
24- // If standard input used for data input just close it.
25- // It will force process to stop (closing files).
26- process . StandardInput . Close ( ) ;
27- }
28- else
29- {
30- // Send "q" to ffmpeg, which will force it to stop (closing files).
31- process . StandardInput . Write ( "q" ) ;
32- }
33- }
34- catch ( InvalidOperationException )
35- {
36- // If the process doesn't exist anymore, ignore it.
37- }
38- finally
39- {
40- // Cancel the task. This will throw an exception to the calling program.
41- // Exc.Message will be "A task was canceled."
42- try
43- {
44- tcs . SetCanceled ( ) ;
45- }
46- catch ( Exception )
47- {
48- }
49- }
50- } ) ;
51- }
8+ public static class ProcessExtensions
9+ {
10+ public static Task < int > WaitForExitAsync ( this Process process , bool stdInDataInput , Action < int > onException , CancellationToken cancellationToken = default )
11+ {
12+ var ctRegistration = new CancellationTokenRegistration ( ) ;
13+ var mustUnregister = false ;
14+ var tcs = new TaskCompletionSource < int > ( ) ;
15+ if ( cancellationToken != default )
16+ {
17+ mustUnregister = true ;
18+ ctRegistration = cancellationToken . Register ( ( ) =>
19+ {
20+ try
21+ {
22+ if ( stdInDataInput )
23+ // If standard input used for data input just close it.
24+ // It will force process to stop (closing files).
25+ process . StandardInput . Close ( ) ;
26+ else
27+ // Send "q" to ffmpeg, which will force it to stop (closing files).
28+ process . StandardInput . Write ( "q" ) ;
29+ }
30+ catch ( InvalidOperationException )
31+ {
32+ // If the process doesn't exist anymore, ignore it.
33+ }
34+ finally
35+ {
36+ // Cancel the task. This will throw an exception to the calling program.
37+ // Exc.Message will be "A task was canceled."
38+ try
39+ {
40+ tcs . SetCanceled ( ) ;
41+ }
42+ catch ( Exception )
43+ {
44+ }
45+ }
46+ } ) ;
47+ }
5248
53- void processOnExited ( object sender , EventArgs e )
54- {
55- process . WaitForExit ( ) ;
56- if ( process . ExitCode != 0 )
57- onException ? . Invoke ( process . ExitCode ) ;
58- tcs . TrySetResult ( process . ExitCode ) ;
59- if ( mustUnregister ) ctRegistration . Dispose ( ) ;
60- process . Exited -= processOnExited ;
61- }
49+ void processOnExited ( object sender , EventArgs e )
50+ {
51+ process . WaitForExit ( ) ;
52+ if ( process . ExitCode != 0 )
53+ onException ? . Invoke ( process . ExitCode ) ;
54+ tcs . TrySetResult ( process . ExitCode ) ;
55+ if ( mustUnregister ) ctRegistration . Dispose ( ) ;
56+ process . Exited -= processOnExited ;
57+ }
6258
63- process . EnableRaisingEvents = true ;
64- process . Exited += processOnExited ;
59+ process . EnableRaisingEvents = true ;
60+ process . Exited += processOnExited ;
6561
66- var started = process . Start ( ) ;
67- if ( ! started )
68- tcs . TrySetException ( new InvalidOperationException ( $ "Could not start process { process } ") ) ;
62+ var started = process . Start ( ) ;
63+ if ( ! started )
64+ tcs . TrySetException ( new InvalidOperationException ( $ "Could not start process { process } ") ) ;
6965
70- process . BeginOutputReadLine ( ) ;
71- process . BeginErrorReadLine ( ) ;
66+ process . BeginOutputReadLine ( ) ;
67+ process . BeginErrorReadLine ( ) ;
7268
73- return tcs . Task ;
74- }
75- }
69+ return tcs . Task ;
70+ }
71+ }
7672}
0 commit comments