From 0da2c1424d000ced00c93eeff582f0a296499df8 Mon Sep 17 00:00:00 2001 From: nilaoda Date: Mon, 31 Oct 2022 02:45:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=960=E9=80=9F=E5=BA=A6=E9=87=8D?= =?UTF-8?q?=E8=AF=95=E9=80=BB=E8=BE=91=20=E9=99=8D=E4=BD=8E=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E5=8D=A0=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Downloader/SimpleDownloader.cs | 34 ++++++++++++++++++- src/N_m3u8DL-RE/Util/DownloadUtil.cs | 21 ++---------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs b/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs index 2feeec8..32db299 100644 --- a/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs +++ b/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace N_m3u8DL_RE.Downloader @@ -55,16 +56,38 @@ namespace N_m3u8DL_RE.Downloader private async Task DownClipAsync(string url, string path, SpeedContainer speedContainer, long? fromPosition, long? toPosition, Dictionary? headers = null, int retryCount = 3) { + CancellationTokenSource? cancellationTokenSource = null; retry: try { + cancellationTokenSource = new(); var des = Path.ChangeExtension(path, null); + //已下载过跳过 if (File.Exists(des)) { return new DownloadResult() { ActualContentLength = 0, ActualFilePath = des }; } - var result = await DownloadUtil.DownloadToFileAsync(url, path, speedContainer, headers, fromPosition, toPosition); + + //另起线程进行监控 + using var watcher = Task.Factory.StartNew(async () => + { + while (true) + { + if (cancellationTokenSource == null || cancellationTokenSource.IsCancellationRequested) break; + if (speedContainer.ShouldStop) + { + cancellationTokenSource.Cancel(); + Logger.DebugMarkUp("Cancel..."); + break; + } + await Task.Delay(500); + } + }); + + //调用下载 + var result = await DownloadUtil.DownloadToFileAsync(url, path, speedContainer, cancellationTokenSource, headers, fromPosition, toPosition); + //下载完成后改名 if (result.Success || !DownloaderConfig.CheckContentLength) { @@ -86,6 +109,15 @@ namespace N_m3u8DL_RE.Downloader //throw new Exception("download failed", ex); return null; } + finally + { + if (cancellationTokenSource != null) + { + //调用后销毁 + cancellationTokenSource.Dispose(); + cancellationTokenSource = null; + } + } } } } diff --git a/src/N_m3u8DL-RE/Util/DownloadUtil.cs b/src/N_m3u8DL-RE/Util/DownloadUtil.cs index c8f2ca8..aa8abdc 100644 --- a/src/N_m3u8DL-RE/Util/DownloadUtil.cs +++ b/src/N_m3u8DL-RE/Util/DownloadUtil.cs @@ -36,7 +36,7 @@ namespace N_m3u8DL_RE.Util }; } - public static async Task DownloadToFileAsync(string url, string path, SpeedContainer speedContainer, Dictionary? headers = null, long? fromPosition = null, long? toPosition = null) + public static async Task DownloadToFileAsync(string url, string path, SpeedContainer speedContainer, CancellationTokenSource cancellationTokenSource, Dictionary? headers = null, long? fromPosition = null, long? toPosition = null) { Logger.Debug(ResString.fetch + url); if (url.StartsWith("file:")) @@ -55,21 +55,6 @@ namespace N_m3u8DL_RE.Util } } Logger.Debug(request.Headers.ToString()); - CancellationTokenSource cancellationTokenSource = new(); //取消下载 - using var watcher = Task.Factory.StartNew(async () => - { - while (true) - { - if (speedContainer == null) break; - if (speedContainer.ShouldStop) - { - cancellationTokenSource.Cancel(); - Logger.DebugMarkUp("Cancel..."); - break; - } - await Task.Delay(500); - } - }); try { using var response = await AppHttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationTokenSource.Token); @@ -90,7 +75,7 @@ namespace N_m3u8DL_RE.Util { redirectedUrl = respHeaders.Location.AbsoluteUri; } - return await DownloadToFileAsync(redirectedUrl, path, speedContainer, headers, fromPosition, toPosition); + return await DownloadToFileAsync(redirectedUrl, path, speedContainer, cancellationTokenSource, headers, fromPosition, toPosition); } } response.EnsureSuccessStatusCode(); @@ -104,7 +89,7 @@ namespace N_m3u8DL_RE.Util while ((size = await responseStream.ReadAsync(buffer, cancellationTokenSource.Token)) > 0) { speedContainer.Add(size); - await stream.WriteAsync(buffer, 0, size, cancellationTokenSource.Token); + await stream.WriteAsync(buffer, 0, size); } return new DownloadResult()