Skip to content
This repository was archived by the owner on Jan 25, 2026. It is now read-only.

Commit 9895508

Browse files
authored
feat: introduce a (incomplete) multi-task downloader (#169)
* init * 🥚 * 再挤一点 * imp: 微调 source report
1 parent 091764c commit 9895508

File tree

10 files changed

+192
-0
lines changed

10 files changed

+192
-0
lines changed

Net/NDownload/IDlConnection.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System.Threading.Tasks;
2+
3+
namespace PCL.Core.Net.NDownload;
4+
5+
/// <summary>
6+
/// 下载连接,负责与服务器进行通信。
7+
/// </summary>
8+
public interface IDlConnection
9+
{
10+
/// <summary>
11+
/// 开始连接,发起与服务器的通信。
12+
/// </summary>
13+
/// <param name="beginOffset">起始偏移,为 <c>0</c> 表示不使用分块</param>
14+
/// <returns>连接信息</returns>
15+
public Task<NDlConnectionInfo> StartAsync(long beginOffset);
16+
17+
/// <summary>
18+
/// 停止连接,同时停止服务器通信并释放资源。
19+
/// </summary>
20+
/// <returns></returns>
21+
public Task StopAsync();
22+
23+
/// <summary>
24+
/// 读取指定长度的数据,若无法继续读取则返回空数组。
25+
/// </summary>
26+
/// <param name="length">读取长度</param>
27+
/// <returns>字节数组形式的数据</returns>
28+
public Task<byte[]> ReadAsync(int length);
29+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace PCL.Core.Net.NDownload;
2+
3+
/// <summary>
4+
/// 资源 ID 映射。
5+
/// </summary>
6+
/// <typeparam name="TMappingValue">映射目标类型</typeparam>
7+
public interface IDlResourceMapping<out TMappingValue>
8+
{
9+
public TMappingValue? Parse(string resId);
10+
}

Net/NDownload/IDlWriter.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.IO;
2+
using System.Threading.Tasks;
3+
4+
namespace PCL.Core.Net.NDownload;
5+
6+
/// <summary>
7+
/// 下载写入器。
8+
/// </summary>
9+
public interface IDlWriter
10+
{
11+
/// <summary>
12+
/// 是否支持并行写入,即是否支持多次调用 <see cref="CreateStreamAsync"/>。
13+
/// </summary>
14+
public bool IsSupportParallel { get; }
15+
16+
/// <summary>
17+
/// 创建写入流。
18+
/// </summary>
19+
/// <returns>写入流</returns>
20+
public Task<Stream> CreateStreamAsync();
21+
22+
/// <summary>
23+
/// 停止写入并释放资源。
24+
/// </summary>
25+
public Task StopAsync();
26+
27+
/// <summary>
28+
/// 完成写入,用于执行某些并行操作的收尾工作 (例如合并文件)。
29+
/// </summary>
30+
public Task FinishAsync();
31+
}

Net/NDownload/NDlConnectionInfo.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace PCL.Core.Net.NDownload;
2+
3+
/// <summary>
4+
/// 下载连接信息。
5+
/// </summary>
6+
/// <param name="Length">内容长度,单位为字节</param>
7+
/// <param name="BeginOffset">起始偏移</param>
8+
/// <param name="EndOffset">结束偏移</param>
9+
/// <param name="IsSupportSegment">是否支持分块</param>
10+
public record NDlConnectionInfo(
11+
long Length,
12+
long BeginOffset,
13+
long EndOffset,
14+
bool IsSupportSegment
15+
);

Net/NDownload/NDlFactory.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
namespace PCL.Core.Net.NDownload;
2+
3+
/// <summary>
4+
/// 无泛型的下载器构建工厂。
5+
/// </summary>
6+
public abstract class NDlFactory
7+
{
8+
/// <summary>
9+
/// 新建连接。
10+
/// </summary>
11+
/// <param name="resId">资源 ID</param>
12+
/// <returns>下载连接</returns>
13+
public abstract IDlConnection? CreateConnection(string resId);
14+
15+
/// <summary>
16+
/// 新建写入器。
17+
/// </summary>
18+
/// <param name="resId">资源 ID</param>
19+
/// <returns>下载写入器</returns>
20+
public abstract IDlWriter? CreateWriter(string resId);
21+
}
22+
23+
/// <summary>
24+
/// 下载器构建工厂。
25+
/// </summary>
26+
/// <typeparam name="TSourceArgument">下载源参数类型</typeparam>
27+
/// <typeparam name="TTargetArgument">写入目标参数类型</typeparam>
28+
public abstract class NDlFactory<TSourceArgument, TTargetArgument> : NDlFactory
29+
{
30+
/// <summary>
31+
/// 下载源映射。
32+
/// </summary>
33+
protected abstract IDlResourceMapping<TSourceArgument> SourceMapping { get; }
34+
35+
/// <summary>
36+
/// 写入目标映射。
37+
/// </summary>
38+
protected abstract IDlResourceMapping<TTargetArgument> TargetMapping { get; }
39+
40+
/// <summary>
41+
/// 新建连接。
42+
/// </summary>
43+
/// <param name="source">下载源参数</param>
44+
/// <returns>下载连接</returns>
45+
protected abstract IDlConnection CreateConnection(TSourceArgument source);
46+
47+
public override IDlConnection? CreateConnection(string resId)
48+
{
49+
var source = SourceMapping.Parse(resId);
50+
return (source == null) ? null : CreateConnection(source);
51+
}
52+
53+
/// <summary>
54+
/// 新建写入器。
55+
/// </summary>
56+
/// <param name="target">写入目标</param>
57+
/// <returns>下载写入器</returns>
58+
protected abstract IDlWriter CreateWriter(TTargetArgument target);
59+
60+
public override IDlWriter? CreateWriter(string resId)
61+
{
62+
var target = TargetMapping.Parse(resId);
63+
return (target == null) ? null : CreateWriter(target);
64+
}
65+
}

Net/NDownload/NDlScheduler.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace PCL.Core.Net.NDownload;
2+
3+
public class NDlScheduler
4+
{
5+
}

Net/NDownload/NDlSourceManager.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
3+
namespace PCL.Core.Net.NDownload;
4+
5+
public class NDlSourceManager<TSourceArgument>(IList<IDlResourceMapping<TSourceArgument>> sources)
6+
: IDlResourceMapping<TSourceArgument>
7+
{
8+
public IList<IDlResourceMapping<TSourceArgument>> Sources { get; } = sources;
9+
10+
public TSourceArgument? Parse(string resId)
11+
{
12+
throw new System.NotImplementedException();
13+
}
14+
}

Net/NDownload/NDlSourceReport.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace PCL.Core.Net.NDownload;
2+
3+
/// <summary>
4+
/// 下载源质量报告
5+
/// </summary>
6+
/// <param name="MaxSegmentCount">支持最大分块数量</param>
7+
/// <param name="RetryCount">重试计数</param>
8+
/// <param name="AverageSpeed">总体平均速度</param>
9+
public record NDlSourceReport(
10+
int MaxSegmentCount = 1,
11+
int RetryCount = 0,
12+
long AverageSpeed = -1
13+
);

Net/NDownload/NDlTask.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace PCL.Core.Net.NDownload;
2+
3+
public class NDlTask
4+
{
5+
}

Net/NDownload/NDlTaskSegment.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace PCL.Core.Net.NDownload;
2+
3+
public class NDlTaskSegment
4+
{
5+
}

0 commit comments

Comments
 (0)