Sage.DownloadLite
1.0.0.4
dotnet add package Sage.DownloadLite --version 1.0.0.4
NuGet\Install-Package Sage.DownloadLite -Version 1.0.0.4
<PackageReference Include="Sage.DownloadLite" Version="1.0.0.4" />
<PackageVersion Include="Sage.DownloadLite" Version="1.0.0.4" />
<PackageReference Include="Sage.DownloadLite" />
paket add Sage.DownloadLite --version 1.0.0.4
#r "nuget: Sage.DownloadLite, 1.0.0.4"
#:package Sage.DownloadLite@1.0.0.4
#addin nuget:?package=Sage.DownloadLite&version=1.0.0.4
#tool nuget:?package=Sage.DownloadLite&version=1.0.0.4
Sage.DownloadLite
一个轻量级、可AOT的.NET下载库,支持 .NET 8 / .NET 9 / .NET 10。提供链式配置、单文件与批量下载、详细进度与结果对象、并发控制、取消与文件冲突处理等特性。适用于控制台、服务端或AOT环境,并可跨平台运行(Windows/Linux/macOS)。
特性
- 轻量简单:围绕
DownloadManager提供清晰的API - 链式配置:
Create().Debug().UserAgent().ConcurrentLimit().Timeout().ProgressInterval() - 完整进度:单任务
SingleDownloadProgress,批量BatchDownloadProgress - 结果对象:单任务
TaskResult,批量BatchDownloadResult - 并发控制:可配置并发上限(默认3,最大10)
- 取消支持:接受
CancellationToken,批量中可因错误回调请求取消 - 文件冲突:可自定义
Skip或Overwrite - AOT友好:无反射与动态生成依赖。
安装
在项目目录执行:
dotnet add package Sage.DownloadLite
或在 csproj 中添加:
<ItemGroup>
<PackageReference Include="Sage.DownloadLite" Version="<最新版本>" />
</ItemGroup>
快速上手
using Sage.DownloadLite.Core;
// 创建下载管理器并链式配置
var manager = DownloadManager.Create()
.Debug(true) // 控制台输出调试信息,可关闭
.UserAgent("MyApp/1.0")
.ConcurrentLimit(3)
.Timeout(TimeSpan.FromMinutes(10))
.ProgressInterval(5); // 进度回调最小百分比间隔 5 即每5%触发进度回调
// 单文件下载(异步)
var result = await manager.DownloadSingleAsync(
url: "https://example.com/file.zip",
filePath: Path.Combine("downloads", "file.zip")
);
if (result.Success)
{
Console.WriteLine($"下载成功: {result.FilePath}, 大小: {result.FormattedFileSize}");
}
else
{
Console.WriteLine($"下载失败: {result.ErrorMessage}");
}
复用与并行示例
同一个 DownloadManager 可以复用执行多个 DownloadSingleAsync(顺序调用):
await manager.DownloadSingleAsync(url1, Path.Combine("downloads", "file1.zip"));
await manager.DownloadSingleAsync(url2, Path.Combine("downloads", "file2.zip"));
await manager.DownloadSingleAsync(url3, Path.Combine("downloads", "file3.zip"));
也可以并行执行多个单文件下载(与批量并发上限无直接绑定):
var task1 = manager.DownloadSingleAsync(url1, Path.Combine("downloads", "file1.zip"));
var task2 = manager.DownloadSingleAsync(url2, Path.Combine("downloads", "file2.zip"));
var task3 = manager.DownloadSingleAsync(url3, Path.Combine("downloads", "file3.zip"));
var results = await Task.WhenAll(task1, task2, task3);
foreach (var r in results)
{
Console.WriteLine($"Task {r.TaskInfo.Id} => {(r.Success ? "OK" : "FAIL")}, {r.FormattedFileSize}, {r.ErrorMessage}");
}
提示:DownloadSingleAsync 理论上没有并发限制,但不推荐过多同时调用。过度并行可能占用过多网络连接、CPU与内存,影响系统稳定性与性能。可结合 SemaphoreSlim、Parallel.ForEachAsync 或自定义限流策略控制并行度,批量下载更推荐使用DownloadBatchAsync
链式配置与回调
Debug(bool enabled):开启/关闭调试输出UserAgent(string ua):设置请求的User-AgentConcurrentLimit(int limit):并发上限(默认3,最大10)Timeout(TimeSpan timeout):下载超时ProgressInterval(double interval):进度更新的最小百分比间隔(默认1%)
回调(可选):
using Sage.DownloadLite.Enums;
using Sage.DownloadLite.Models;
var manager = DownloadManager.Create()
.OnProgress(progress =>
{
// 单任务进度
Console.WriteLine($"Task {progress.Task.Id} {progress.Percentage:F1}% " +
$"({progress.FormattedDownloaded}/{progress.FormattedTotal}) " +
$"速度: {progress.FormattedSpeed}");
})
.OnError((task, ex) =>
{
// 单任务错误(返回值在单任务中仅用于记录,不影响流程)
Console.WriteLine($"Task {task.Id} 错误: {ex.Message}");
return true; // 建议true
})
.OnFileConflict((task, path) =>
{
// 文件已存在时:选择跳过或覆盖
Console.WriteLine($"文件已存在: {path},选择覆盖");
return FileExistsAction.Overwrite; // 或 FileExistsAction.Skip
})
.OnBatchProgress(batch =>
{
// 批量进度
Console.WriteLine($"批量进度: {batch.Percentage:F1}% " +
$"完成/总计: {batch.CompletedTasks}/{batch.TotalTasks} 成功: {batch.SuccessfulTasks} 失败: {batch.FailedTasks}");
})
.OnBatchError((task, ex) =>
{
// 批量错误:返回false将请求取消后续任务
Console.WriteLine($"批量任务 {task.Id} 错误: {ex.Message}");
return true; // 返回false将触发批量取消
})
.OnTaskCompleted((task, file) =>
{
Console.WriteLine($"任务完成: {task.Id}, 文件: {file.FullName}, 大小: {file.Length}");
});
批量下载示例
using Sage.DownloadLite.Core;
using Sage.DownloadLite.Models;
var tasks = new List<TaskInfo>
{
DownloadManager.CreateTaskInfo("https://example.com/a.jpg", Path.Combine("downloads", "a.jpg")),
DownloadManager.CreateTaskInfo("https://example.com/b.jpg", Path.Combine("downloads", "b.jpg")),
DownloadManager.CreateTaskInfo("https://example.com/c.jpg", Path.Combine("downloads", "c.jpg"))
};
using var cts = new CancellationTokenSource();
var batch = await manager.DownloadBatchAsync(tasks, cts.Token);
Console.WriteLine($"成功: {batch.SuccessfulTasks}, 失败: {batch.FailedTasks}, 取消: {batch.CancelledTasksCount}");
Console.WriteLine($"总大小: {batch.FormattedTotalSize}, 耗时: {batch.TotalTime}");
foreach (var tr in batch.CompletedTasks)
{
Console.WriteLine($"Task {tr.TaskInfo.Id} => {(tr.Success ? "OK" : "FAIL")}, {tr.FormattedFileSize}, {tr.ErrorMessage}");
}
进度与结果对象
单任务进度 SingleDownloadProgress:
Task:任务信息对象(TaskInfo)DownloadedBytes:已下载字节数TotalBytes:总字节数(未知时为-1)Percentage:当前下载百分比(0–100)Speed:当前速度(字节/秒)FormattedDownloaded:格式化后的已下载大小(如12.3 MB)FormattedTotal:格式化后的总大小(如54.2 MB)FormattedSpeed:格式化后的下载速度(如1.2 MB/s)
单任务结果 TaskResult:
TaskInfo:任务信息对象(包含ID/URL/文件路径/状态等)Success:是否成功FilePath:下载文件的本地路径FileSize:文件大小(字节)Error:异常对象(失败或取消时)ErrorMessage:错误消息(等同于Error?.Message)Status:任务状态(Waiting/Downloading/Completed/Failed/Cancelled)Duration:下载耗时(EndTime - StartTime)StartTime:开始时间EndTime:结束时间FormattedFileSize:格式化后的文件大小(如32.0 MB)
批量进度 BatchDownloadProgress:
CompletedTasks:已完成任务数(含成功与失败)TotalTasks:总任务数Percentage:总体进度百分比(0–100)CurrentTask:当前正在处理的任务信息(TaskInfo)SuccessfulTasks:成功任务数FailedTasks:失败任务数
批量结果 BatchDownloadResult:
Success:是否全部成功(全部成功且无取消)CompletedTasks:已完成任务的结果列表(含成功与失败)CancelledTasks:被取消任务的结果列表ErrorMessage:批量级错误消息(如批量流程异常)TotalTime:总耗时(EndTime - StartTime)StartTime:批量开始时间EndTime:批量结束时间TotalTasks:总任务数(CompletedTasks.Count + CancelledTasks.Count)SuccessfulTasks:成功任务数(CompletedTasks中Success==true的数量)FailedTasks:失败任务数(CompletedTasks中Success==false的数量)CancelledTasksCount:取消任务数(CancelledTasks.Count)SuccessRate:成功率百分比(SuccessfulTasks / TotalTasks * 100)TotalDownloadedSize:成功任务下载文件大小总和(字节)FormattedTotalSize:格式化后的总下载大小(如128.6 MB)
回调类型说明(参数含义简表)
OnProgress(Action<SingleDownloadProgress>):单任务进度;包含任务ID、百分比、速度与格式化大小OnError(Func<TaskInfo, Exception, bool>):单任务错误;返回值用于记录(建议返回true)OnFileConflict(Func<TaskInfo, string, FileExistsAction>):处理文件已存在;返回Skip跳过或Overwrite覆盖OnBatchProgress(Action<BatchDownloadProgress>):批量进度;包含完成数、总数、成功/失败统计与总体百分比OnBatchError(Func<TaskInfo, Exception, bool>):批量错误;返回false将请求取消后续任务OnTaskCompleted(Action<TaskInfo, FileInfo>):单个任务完成;提供文件信息(路径、大小)
辅助枚举与状态
TaskStatus:Waiting(等待)、Downloading(下载中)、Completed(完成)、Failed(失败)、Cancelled(取消)FileExistsAction:Skip(跳过)、Overwrite(覆盖)
同步API
为方便在某些上下文调用(如控制台程序),提供同步包装:
TaskResult DownloadSingle(string url, string filePath)TaskResult DownloadSingle(TaskInfo taskInfo)BatchDownloadResult DownloadBatch(IEnumerable<TaskInfo> tasks)
注意:同步方法内部使用 Task.Run().GetAwaiter().GetResult(),建议在不阻塞UI线程的环境中使用。
取消与并发
- 单任务与批量方法均接受
CancellationToken,支持取消。 - 批量下载中,
OnBatchError回调返回false将请求取消当前和后续任务。 - 并发上限通过
ConcurrentLimit(int)配置,默认 3,最大 10;实际并发通过SemaphoreSlim控制。 DownloadSingleAsync并无硬性并发限制;如需大量并行,请自行控制并行度,避免资源耗尽。
文件冲突处理
- 无回调时:默认覆盖
- 有
OnFileConflict时:依据返回值FileExistsAction.Skip(跳过)或Overwrite(覆盖) - 当选择
Skip:对应任务将被标记为取消并加入BatchDownloadResult.CancelledTasks
调试与日志
- 通过
Debug(true)可开启调试输出;内部使用System.Diagnostics.Debug.WriteLine与Console.WriteLine。 - 生产环境可关闭:
Debug(false)。
许可证
许可证:Apache-2.0(兼容商业与开源使用)。
跨平台:依赖 HttpClient,可在 Windows / Linux / macOS 上运行(满足 .NET 8/9/10 的运行环境)。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
更新基础库