public async Task <IAttemptResult <IEnumerable <IListVideoInfo> > > GetVideoListInfosAsync(IEnumerable <string> ids, Action <string>?onSucceeded = null, CancellationToken?ct = null) { var videos = new List <IListVideoInfo>(); int videosCount = ids.Count(); int maxParallelCount = this._settingHandler.GetIntSetting(SettingsEnum.MaxFetchCount); int waitInterval = this._settingHandler.GetIntSetting(SettingsEnum.FetchSleepInterval); if (maxParallelCount < 1) { maxParallelCount = NetConstant.DefaultMaxParallelFetchCount; } if (waitInterval < 1) { waitInterval = NetConstant.DefaultFetchWaitInterval; } var handler = new ParallelTasksHandler <NetworkVideoParallelTask>(maxParallelCount, waitInterval, 15); foreach (var id in ids) { var task = new NetworkVideoParallelTask(async(_, lockObj) => { IAttemptResult <IListVideoInfo> result = await this.GetVideoListInfoAsync(id, ct); if (result.IsSucceeded && result.Data is not null) { videos.Add(result.Data); onSucceeded?.Invoke(id); } }, index => this._messageHandler.AppendMessage("待機中...(15s)")); handler.AddTaskToQueue(task); } await handler.ProcessTasksAsync(() => { }, () => this._messageHandler.AppendMessage("動画情報の取得処理が中断されました。"), ct ?? CancellationToken.None); return(AttemptResult <IEnumerable <IListVideoInfo> > .Succeeded(videos)); }
public async Task <IAttemptResult> DownloadAsync(IStreamInfo stream, Action <string> onMessage, IDownloadContext context, int maxParallelDownloadCount, string segmentDirectoryName, CancellationToken token) { //変数の初期化 var taskHandler = new ParallelTasksHandler <IParallelDownloadTask>(maxParallelDownloadCount, false); int completed = context.OriginalSegmentsCount - stream.StreamUrls.Count; int all = context.OriginalSegmentsCount; string resolution = context.ActualVerticalResolution == 0 ? string.Empty : $"({context.ActualVerticalResolution}px)"; var failedInOne = false; var tasks = stream.StreamUrls.Select(url => new ParallelDownloadTask(async(self, _) => { if (token.IsCancellationRequested || failedInOne) { self.SetResult(AttemptResult.Fail()); return; } byte[] data; try { data = await this.DownloadInternalAsync(self.Url, self.Context, token); } catch (Exception e) { self.SetResult(AttemptResult.Fail(null, e)); this._logger.Error($"セグメント(idx:{self.SequenceZero})の取得に失敗しました。({context.GetLogContent()})", e); failedInOne = true; return; } this._logger.Log($"セグメント(idx:{self.SequenceZero})を取得しました。({context.GetLogContent()})"); if (token.IsCancellationRequested) { self.SetResult(AttemptResult.Fail()); return; } try { this._writer.Write(data, self, segmentDirectoryName); } catch (Exception e) { self.SetResult(AttemptResult.Fail(null, e)); this._logger.Error($"セグメント(idx:{self.SequenceZero})の書き込みに失敗しました。({context.GetLogContent()})", e); failedInOne = true; return; } completed++; onMessage($"完了: {completed}/{all}{resolution}"); self.SetResult(AttemptResult.Succeeded()); await Task.Delay(1 * 1000, token); }, context, url.AbsoluteUrl, url.SequenceZero, url.FileName)); foreach (var task in tasks) { taskHandler.AddTaskToQueue(task); } await taskHandler.ProcessTasksAsync(ct : token); foreach (var task in tasks) { if (task.Result is not null && !task.Result.IsSucceeded) { return(task.Result); } } return(AttemptResult.Succeeded()); }