261 lines
7.4 KiB
C#
261 lines
7.4 KiB
C#
using System.Collections.Concurrent;
|
||
using System.Collections.ObjectModel;
|
||
using System.ComponentModel;
|
||
using System.Diagnostics;
|
||
using System.Windows.Data;
|
||
using System.Windows.Input;
|
||
using HeBianGu.Base.WpfBase;
|
||
using HeBianGu.Service.Mvc;
|
||
using Hopetry.Models;
|
||
using Hopetry.Provider;
|
||
using Hopetry.Services;
|
||
using Newtonsoft.Json;
|
||
|
||
namespace Hopetry.ViewModel.Send;
|
||
|
||
[ViewModel("Down")]
|
||
public class DownViewModel : MvcViewModelBase
|
||
{
|
||
private readonly MinioService _minioService;
|
||
|
||
public RelayCommand<MinioDownloadTask> OpenDownItemFolder { get; set; }
|
||
private readonly ConcurrentQueue<MinioDownloadTask> _taskQueue = new();
|
||
private SemaphoreSlim _semaphore;
|
||
|
||
private CancellationTokenSource _processingCts = new();
|
||
public int count { get; set; }
|
||
private readonly ReaderWriterLockSlim _lock = new();
|
||
|
||
|
||
/// <summary>
|
||
/// 全部任务动态标题
|
||
/// </summary>
|
||
private string _allTaskHeader;
|
||
|
||
public string AllTaskHeader
|
||
{
|
||
get => _allTaskHeader;
|
||
set
|
||
{
|
||
_allTaskHeader = value;
|
||
RaisePropertyChanged();
|
||
}
|
||
}
|
||
|
||
private string _runningTaskHeader;
|
||
|
||
public string RunningTaskHeader
|
||
{
|
||
get => _runningTaskHeader;
|
||
set
|
||
{
|
||
_runningTaskHeader = value;
|
||
RaisePropertyChanged();
|
||
}
|
||
}
|
||
|
||
private string _finishedTaskHeader;
|
||
|
||
public string FinishedTaskHeader
|
||
{
|
||
get => _finishedTaskHeader;
|
||
set
|
||
{
|
||
_finishedTaskHeader = value;
|
||
RaisePropertyChanged();
|
||
}
|
||
}
|
||
|
||
// 绑定属性
|
||
public ObservableCollection<MinioDownloadTask> AllTasks { get; set; }
|
||
|
||
|
||
public ICollectionView RunningTasksView { get; set; }
|
||
public ICollectionView FinishedTasksView { get; set; }
|
||
private int _maxConcurrent = 3;
|
||
|
||
public int MaxConcurrent
|
||
{
|
||
get => _maxConcurrent;
|
||
set
|
||
{
|
||
if (value < 1) value = 1;
|
||
if (_maxConcurrent == value) return;
|
||
|
||
_maxConcurrent = value;
|
||
//AdjustConcurrency();
|
||
RaisePropertyChanged();
|
||
}
|
||
}
|
||
|
||
private int _runningTasks;
|
||
|
||
public int RunningTasks
|
||
{
|
||
get => _runningTasks;
|
||
private set
|
||
{
|
||
_runningTasks = value;
|
||
RaisePropertyChanged();
|
||
}
|
||
}
|
||
|
||
// 命令
|
||
public ICommand AddTaskCommand { get; set; }
|
||
public ICommand ClearFinishedCommand { get; }
|
||
private readonly ISerializerService _serializerService;
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="minioService"></param>
|
||
public DownViewModel(MinioService minioService, ISerializerService serializerService)
|
||
{
|
||
_serializerService = serializerService;
|
||
_minioService = minioService;
|
||
Console.WriteLine("初始化DownViewModel");
|
||
using var client = SqlSugarConfig.GetSqlSugarScope();
|
||
var data = client.Ado.SqlQuery<MinioDownloadTask>($"select * from download_task");
|
||
AllTasks = new ObservableCollection<MinioDownloadTask>(data);
|
||
AllTaskHeader = $"全部({AllTasks.Count})";
|
||
//Console.WriteLine(JsonConvert.SerializeObject(data));
|
||
OpenDownItemFolder = new RelayCommand<MinioDownloadTask>(DoOpenDownItemFolder);
|
||
var cvsRunning = new CollectionViewSource { Source = AllTasks };
|
||
cvsRunning.Filter += (s, e) =>
|
||
{
|
||
var b = ((MinioDownloadTask)e.Item).Status is "下载中" or "等待中" or "已暂停";
|
||
e.Accepted = b;
|
||
};
|
||
RunningTasksView = cvsRunning.View;
|
||
|
||
var cvsFinished = new CollectionViewSource { Source = AllTasks };
|
||
cvsFinished.Filter += (s, e) =>
|
||
{
|
||
var b = ((MinioDownloadTask)e.Item).Status == "已完成";
|
||
e.Accepted = b;
|
||
};
|
||
FinishedTasksView = cvsFinished.View;
|
||
RefreshViewHeader();
|
||
|
||
// 关键:订阅数据源变更事件,强制视图刷新
|
||
AllTasks.CollectionChanged += (s, e) =>
|
||
{
|
||
RunningTasksView.Refresh();
|
||
FinishedTasksView.Refresh();
|
||
};
|
||
|
||
ClearFinishedCommand = new CustomCommand(() =>
|
||
{
|
||
// todo 删除已完成的下载记录
|
||
});
|
||
|
||
// 启动任务处理线程
|
||
_semaphore = new SemaphoreSlim(_maxConcurrent);
|
||
new Thread(ProcessTasksLoop) { IsBackground = true }.Start();
|
||
//AddTaskCommand = new ActionCommand(AddTask);
|
||
}
|
||
|
||
private void RefreshViewHeader()
|
||
{
|
||
if (FinishedTasksView is ListCollectionView finishListView)
|
||
{
|
||
FinishedTaskHeader = $"已完成({finishListView.Count})";
|
||
}
|
||
|
||
if (RunningTasksView is ListCollectionView runningListView)
|
||
{
|
||
RunningTaskHeader = $"下载中({runningListView.Count})";
|
||
}
|
||
}
|
||
|
||
private async void ProcessTasksLoop()
|
||
{
|
||
int c1 = 1;
|
||
while (!_processingCts.IsCancellationRequested)
|
||
{
|
||
await _semaphore.WaitAsync();
|
||
Console.WriteLine("获得下载许可");
|
||
if (_taskQueue.TryDequeue(out var task))
|
||
{
|
||
Console.WriteLine($"开启下载任务:{c1++}");
|
||
// 启动新线程执行下载任务
|
||
// _ = Task.Run(() => ExecuteTaskAsync(task));
|
||
_ = ExecuteTaskAsync(task).ContinueWith(_ => _semaphore.Release());
|
||
}
|
||
|
||
Thread.Sleep(100);
|
||
}
|
||
}
|
||
|
||
public void AddTask(string bucketName, string objectKey)
|
||
{
|
||
var downDir = ViewModelLocator.SyncViewModel.SyncDir;
|
||
var task = new MinioDownloadTask(_minioService, bucketName, objectKey,downDir);
|
||
using var client = SqlSugarConfig.GetSqlSugarScope();
|
||
client.Insertable(task).ExecuteCommandIdentityIntoEntity();
|
||
AllTasks.Add(task);
|
||
_taskQueue.Enqueue(task);
|
||
RefreshViewHeader();
|
||
}
|
||
|
||
|
||
private async Task ExecuteTaskAsync(MinioDownloadTask task)
|
||
{
|
||
try
|
||
{
|
||
await task.StartDownload();
|
||
var x = AllTasks.IndexOf(task);
|
||
var temp = AllTasks[x];
|
||
temp.Status = "已完成";
|
||
Console.WriteLine($"所有任务取出任务id {temp.TaskId} 完成任务id:{task.TaskId}" );
|
||
Console.WriteLine($"完成任务在全部任务中的位置 :{x}");
|
||
RefreshViewHeader();
|
||
Console.WriteLine($"异步下载完成:{task.FileName}");
|
||
}
|
||
finally
|
||
{
|
||
}
|
||
}
|
||
|
||
private void AdjustConcurrency()
|
||
{
|
||
lock (_semaphore)
|
||
{
|
||
// 调整信号量容量
|
||
var delta = _maxConcurrent - _semaphore.CurrentCount;
|
||
if (delta > 0)
|
||
{
|
||
for (int i = 0; i < delta; i++)
|
||
{
|
||
_semaphore.Release();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public void DoOpenDownItemFolder(MinioDownloadTask para)
|
||
{
|
||
Console.WriteLine($"点击item值:{JsonConvert.SerializeObject(para)}");
|
||
Process.Start("explorer.exe", para.FilePath);
|
||
}
|
||
|
||
public void DoCancelDownItem(MinioDownloadTask item)
|
||
{
|
||
Console.WriteLine("取消下载");
|
||
// todo 实现取消下载
|
||
}
|
||
|
||
public void DoPauseDownItem(MinioDownloadTask item)
|
||
{
|
||
Console.WriteLine("暂停下载");
|
||
// todo 实现暂停下载
|
||
}
|
||
|
||
protected override void Init()
|
||
{
|
||
}
|
||
|
||
protected override void Loaded(string args)
|
||
{
|
||
}
|
||
} |