ZeroLauncher/dialog/DownloadControl.xaml.cs
2024-03-07 21:04:59 +08:00

105 lines
3.8 KiB
C#

using System.IO;
using System.Net.Http;
using System.Windows.Controls;
namespace Zerolauncher.dialog
{
/// <summary>
/// DownloadControl.xaml 的交互逻辑
/// </summary>
public partial class DownloadControl : UserControl
{
const string cache_dir = "./.cache/auto.cache";
public DownloadControl()
{
InitializeComponent();
}
private void OnError(Exception ex)
{
// UnityEngine.Debug.Log("捕获异常 >>> " + ex);
}
public async Task Download(string fileUrl)
{
using (HttpClient client = new HttpClient())
{
// 获取文件大小
HttpResponseMessage responseHead = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, fileUrl));
long? contentLength = responseHead.Content.Headers.ContentLength;
Console.WriteLine($"文件大小:{contentLength} 字节");
// 计算块大小
int blockSize = 1024 * 1024; // 1MB
int blockCount = (int)Math.Ceiling((double)contentLength / blockSize);
// 创建SemaphoreSlim以限制同时进行的下载任务的数量
SemaphoreSlim semaphore = new SemaphoreSlim(4); // 最多允许4个并发下载任务
using (FileStream fileStream = new FileStream(cache_dir, FileMode.Create, FileAccess.Write, FileShare.None, blockSize, true))
{
// 创建任务列表
Task[] tasks = new Task[blockCount];
for (int i = 0; i < blockCount; i++)
{
int blockNumber = i;
tasks[i] = Task.Run(async () =>
{
await semaphore.WaitAsync(); // 等待获取许可
try
{
// 计算当前块的范围
var start = blockNumber * blockSize;
var end = (blockNumber == blockCount - 1) ? contentLength - 1 : start + blockSize - 1;
// 设置请求头,请求指定范围的数据
var request = new HttpRequestMessage { RequestUri = new Uri(fileUrl), Method = HttpMethod.Get };
request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(start, end);
// 下载当前块
using (HttpResponseMessage response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
byte[] buffer = await response.Content.ReadAsByteArrayAsync();
await fileStream.WriteAsync(buffer, 0, buffer.Length);
}
// 显示下载进度
double percent = (double)(blockNumber + 1) / blockCount * 100;
Console.WriteLine($"已下载:{percent:F2}%");
}
finally
{
semaphore.Release(); // 释放许可
}
});
}
// 等待所有任务完成
await Task.WhenAll(tasks);
}
}
Console.WriteLine("下载完成!");
}
private void OnUpdate(long size, long count)
{
}
private void OnDone(byte[] data)
{
}
private void OnDestroy()
{
}
}
}