88using System . Globalization ;
99using System . IO ;
1010using System . Linq ;
11- using System . Reactive . Concurrency ;
1211using System . Text ;
1312using System . Threading ;
1413using System . Threading . Tasks ;
@@ -64,19 +63,49 @@ public BackendInstance(ObservableSettings settings, BackendService backendServic
6463 _dlProcess . StartInfo . StandardErrorEncoding = Encoding . UTF8 ;
6564 _dlProcess . StartInfo . StandardOutputEncoding = Encoding . UTF8 ;
6665 _dlProcess . EnableRaisingEvents = true ;
67- _dlProcess . ErrorDataReceived += DlOutputHandler ;
68- _dlProcess . OutputDataReceived += DlOutputHandler ;
69- _dlProcess . Exited += DlProcess_Exited ;
7066 }
7167
72- private void DlOutputHandler ( object ? sendingProcess , DataReceivedEventArgs outLine )
68+ private async Task RunDlAsync ( CancellationToken cancellationToken = default )
7369 {
74- if ( outLine . Data is null )
75- return ;
70+ if ( ! _dlProcess . Start ( ) )
71+ throw new InvalidOperationException ( "Method called when the backend process is running." ) ;
7672
77- this . Log ( ) . Info ( outLine . Data ) ;
73+ SetStatusRunning ( ) ;
7874
79- RxApp . MainThreadScheduler . Schedule ( ( ) => ParseDlOutput ( outLine . Data ) ) ;
75+ await Task . WhenAll (
76+ ReadAndParseAsync ( _dlProcess . StandardError , cancellationToken ) ,
77+ ReadAndParseAsync ( _dlProcess . StandardOutput , cancellationToken ) ,
78+ _dlProcess . WaitForExitAsync ( cancellationToken ) ) ;
79+
80+ SetStatusStopped ( ) ;
81+ }
82+
83+ private void SetStatusRunning ( )
84+ {
85+ StatusIndeterminate = true ;
86+ IsRunning = true ;
87+ _backendService . UpdateProgress ( ) ;
88+ }
89+
90+ private void SetStatusStopped ( )
91+ {
92+ DownloadProgressPercentage = 0.0 ;
93+ StatusIndeterminate = false ;
94+ IsRunning = false ;
95+ _backendService . UpdateProgress ( ) ;
96+ }
97+
98+ private async Task ReadAndParseAsync ( StreamReader reader , CancellationToken cancellationToken = default )
99+ {
100+ while ( true )
101+ {
102+ var line = await reader . ReadLineAsync ( cancellationToken ) ;
103+ if ( line is null )
104+ return ;
105+
106+ this . Log ( ) . Info ( line ) ;
107+ ParseDlOutput ( line ) ;
108+ }
80109 }
81110
82111 private void ParseDlOutput ( string output )
@@ -106,20 +135,6 @@ private void ParseDlOutput(string output)
106135 }
107136 }
108137
109- private void DlProcess_Exited ( object ? sender , EventArgs e )
110- {
111- _dlProcess . CancelErrorRead ( ) ;
112- _dlProcess . CancelOutputRead ( ) ;
113-
114- RxApp . MainThreadScheduler . Schedule ( ( ) =>
115- {
116- DownloadProgressPercentage = 0.0 ;
117- StatusIndeterminate = false ;
118- IsRunning = false ;
119- _backendService . UpdateProgress ( ) ;
120- } ) ;
121- }
122-
123138 public void GenerateDownloadArguments ( )
124139 {
125140 GeneratedDownloadArguments . Clear ( ) ;
@@ -231,7 +246,7 @@ public void GenerateDownloadArguments()
231246 }
232247 }
233248
234- public void StartDownload ( string link )
249+ public async Task StartDownloadAsync ( string link , CancellationToken cancellationToken = default )
235250 {
236251 _dlProcess . StartInfo . FileName = _settings . BackendPath ;
237252 _dlProcess . StartInfo . ArgumentList . Clear ( ) ;
@@ -242,21 +257,15 @@ public void StartDownload(string link)
242257
243258 try
244259 {
245- _dlProcess . Start ( ) ;
246- _dlProcess . BeginErrorReadLine ( ) ;
247- _dlProcess . BeginOutputReadLine ( ) ;
248-
249- StatusIndeterminate = true ;
250- IsRunning = true ;
251- _backendService . UpdateProgress ( ) ;
260+ await RunDlAsync ( cancellationToken ) ;
252261 }
253262 catch ( Exception ex )
254263 {
255264 this . Log ( ) . Error ( ex ) ;
256265 }
257266 }
258267
259- public void ListFormats ( string link )
268+ public async Task ListFormatsAsync ( string link , CancellationToken cancellationToken = default )
260269 {
261270 _dlProcess . StartInfo . FileName = _settings . BackendPath ;
262271 _dlProcess . StartInfo . ArgumentList . Clear ( ) ;
@@ -271,21 +280,15 @@ public void ListFormats(string link)
271280
272281 try
273282 {
274- _dlProcess . Start ( ) ;
275- _dlProcess . BeginErrorReadLine ( ) ;
276- _dlProcess . BeginOutputReadLine ( ) ;
277-
278- StatusIndeterminate = true ;
279- IsRunning = true ;
280- _backendService . UpdateProgress ( ) ;
283+ await RunDlAsync ( cancellationToken ) ;
281284 }
282285 catch ( Exception ex )
283286 {
284287 this . Log ( ) . Error ( ex ) ;
285288 }
286289 }
287290
288- public async Task AbortDl ( CancellationToken cancellationToken = default )
291+ public async Task AbortDlAsync ( CancellationToken cancellationToken = default )
289292 {
290293 if ( CtrlCHelper . AttachConsole ( ( uint ) _dlProcess . Id ) )
291294 {
@@ -310,7 +313,7 @@ public async Task AbortDl(CancellationToken cancellationToken = default)
310313 this . Log ( ) . Info ( "🛑 Aborted." ) ;
311314 }
312315
313- public void UpdateDl ( )
316+ public async Task UpdateDlAsync ( CancellationToken cancellationToken = default )
314317 {
315318 _settings . BackendLastUpdateCheck = DateTimeOffset . Now ;
316319
@@ -325,13 +328,7 @@ public void UpdateDl()
325328
326329 try
327330 {
328- _dlProcess . Start ( ) ;
329- _dlProcess . BeginErrorReadLine ( ) ;
330- _dlProcess . BeginOutputReadLine ( ) ;
331-
332- StatusIndeterminate = true ;
333- IsRunning = true ;
334- _backendService . UpdateProgress ( ) ;
331+ await RunDlAsync ( cancellationToken ) ;
335332 }
336333 catch ( Exception ex )
337334 {
0 commit comments