FieldWorkClient/ViewModel/Send/DownViewModel.cs

340 lines
9.4 KiB
C#
Raw Normal View History

using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
2025-04-14 13:52:04 +08:00
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Shapes;
2025-04-15 14:05:06 +08:00
using System.Windows.Threading;
2025-04-08 16:22:25 +08:00
using HeBianGu.Base.WpfBase;
using HeBianGu.Service.Mvc;
using Hopetry.Models;
using Hopetry.Provider;
using Hopetry.Services;
using Newtonsoft.Json;
using Path = System.IO.Path;
2025-04-08 16:22:25 +08:00
namespace Hopetry.ViewModel.Send;
[ViewModel("Down")]
public class DownViewModel : MvcViewModelBase
{
private readonly MinioService _minioService;
2025-04-12 13:23:12 +08:00
public RelayCommand<MinioDownloadTask> OpenDownItemFolder { get; set; }
private readonly ConcurrentQueue<MinioDownloadTask> _taskQueue = new();
2025-04-12 15:50:38 +08:00
private SemaphoreSlim _semaphore;
private CancellationTokenSource _processingCts = new();
2025-04-12 13:23:12 +08:00
public int count { get; set; }
private readonly ReaderWriterLockSlim _lock = new();
2025-04-14 13:52:04 +08:00
private Visibility _tab0Visibility;
2025-04-14 13:52:04 +08:00
public Visibility Tab0Visibility
{
get => _tab0Visibility;
set
{
_tab0Visibility = value;
RaisePropertyChanged();
}
}
private Visibility _tab1Visibility;
2025-04-14 13:52:04 +08:00
public Visibility Tab1Visibility
{
get => _tab1Visibility;
set
{
_tab1Visibility = value;
RaisePropertyChanged();
}
}
2025-04-14 13:52:04 +08:00
private int _tabIndex;
public int TabIndex
{
get => _tabIndex;
set
{
_tabIndex = value;
if (_tabIndex == 0)
{
Tab0Visibility = Visibility.Visible;
Tab1Visibility = Visibility.Hidden;
}
else if (_tabIndex == 1)
{
Tab0Visibility = Visibility.Hidden;
Tab1Visibility = Visibility.Visible;
}
RaisePropertyChanged();
}
}
/// <summary>
/// 全部任务动态标题
/// </summary>
2025-04-10 14:31:05 +08:00
private string _allTaskHeader;
public string AllTaskHeader
{
2025-04-10 14:31:05 +08:00
get => _allTaskHeader;
set
{
_allTaskHeader = value;
RaisePropertyChanged();
}
}
private string _runningTaskHeader;
public string RunningTaskHeader
{
get => _runningTaskHeader;
set
{
2025-04-10 14:31:05 +08:00
_runningTaskHeader = value;
RaisePropertyChanged();
}
}
private string _finishedTaskHeader;
public string FinishedTaskHeader
{
get => _finishedTaskHeader;
set
{
_finishedTaskHeader = value;
RaisePropertyChanged();
}
}
// 绑定属性
//public ObservableCollection<MinioDownloadTask> AllTasks { get; set; }
private ObservableCollection<MinioDownloadTask> _runningTasks;
2025-04-12 13:23:12 +08:00
public ObservableCollection<MinioDownloadTask> RunningTasks
{
get => _runningTasks;
set
{
_runningTasks = value;
RaisePropertyChanged(); // 触发INotifyPropertyChanged通知
}
}
private ObservableCollection<MinioDownloadTask> _finishedTasks;
2025-04-15 14:05:06 +08:00
public ObservableCollection<MinioDownloadTask> FinishedTasks
{
get => _finishedTasks;
set
{
_finishedTasks = value;
RaisePropertyChanged(); // 触发INotifyPropertyChanged通知
}
}
2025-04-15 14:05:06 +08:00
private int _maxConcurrent = 3;
public int MaxConcurrent
{
get => _maxConcurrent;
set
{
if (value < 1) value = 1;
if (_maxConcurrent == value) return;
_maxConcurrent = value;
2025-04-12 13:23:12 +08:00
//AdjustConcurrency();
RaisePropertyChanged();
}
}
public ICommand ClearFinishedCommand { get; }
2025-04-15 14:05:06 +08:00
public RelayCommand<MinioDownloadTask> StartOrPauseDown { get; }
2025-04-08 16:22:25 +08:00
2025-04-10 14:31:05 +08:00
/// <summary>
/// 构造函数
/// </summary>
/// <param name="minioService"></param>
public DownViewModel(MinioService minioService)
2025-04-08 16:22:25 +08:00
{
_minioService = minioService;
Console.WriteLine("初始化DownViewModel");
2025-04-12 13:23:12 +08:00
using var client = SqlSugarConfig.GetSqlSugarScope();
OpenDownItemFolder = new RelayCommand<MinioDownloadTask>(DoOpenDownItemFolder);
2025-04-15 14:05:06 +08:00
StartOrPauseDown = new RelayCommand<MinioDownloadTask>(DoStartOrPauseDown);
LoadFinishedTasks();
LoadRunningTasks();
ClearFinishedCommand = new CustomCommand(DoClearFinishedCommand);
// 启动任务处理线程
_semaphore = new SemaphoreSlim(MaxConcurrent);
new Thread(ProcessTasksLoop) { IsBackground = true }.Start();
}
2025-04-10 14:31:05 +08:00
2025-04-15 14:05:06 +08:00
private void DoStartOrPauseDown(MinioDownloadTask item)
{
if (item.Status == "下载中")
{
item.Status = "已暂停";
// TODO 暂停下载
}
else if (item.Status == "已暂停")
{
item.Status = "下载中";
_taskQueue.Enqueue(item);
}
}
private void DoClearFinishedCommand()
{
using var client = SqlSugarConfig.GetSqlSugarScope();
client.Deleteable<MinioDownloadTask>().Where(x => x.Status == "已完成").ExecuteCommand();
FinishedTasks.Clear();
FinishedTaskHeader = $"已完成0";
}
2025-04-14 13:52:04 +08:00
public void RefreshHeader()
{
RunningTaskHeader = $"下载中({RunningTasks.Count}";
FinishedTaskHeader = $"已完成({FinishedTasks.Count}";
}
public void LoadRunningTasks()
{
2025-04-15 14:05:06 +08:00
// todo 队列中有几种任务状态 数据库中应该有几种任务状态
//
using var client = SqlSugarConfig.GetSqlSugarScope();
var data = client.Ado
.SqlQuery<MinioDownloadTask>(
$"select * from download_task where status='下载中' or status='等待中' or status='已暂停' order by task_id desc");
RunningTasks = new ObservableCollection<MinioDownloadTask>(data);
RunningTaskHeader = $"下载中({RunningTasks.Count}";
}
2025-04-12 13:23:12 +08:00
public void LoadFinishedTasks()
{
using var client = SqlSugarConfig.GetSqlSugarScope();
var data = client.Ado
2025-04-15 14:05:06 +08:00
.SqlQuery<MinioDownloadTask>(
$"select * from download_task where status='已完成' order by datetime(finished_time) desc");
FinishedTasks = new ObservableCollection<MinioDownloadTask>(data);
FinishedTaskHeader = $"已完成({FinishedTasks.Count}";
2025-04-12 15:50:38 +08:00
}
2025-04-12 13:23:12 +08:00
2025-04-12 15:50:38 +08:00
private async void ProcessTasksLoop()
{
2025-04-12 15:50:38 +08:00
int c1 = 1;
while (!_processingCts.IsCancellationRequested)
{
2025-04-12 15:50:38 +08:00
if (_taskQueue.TryDequeue(out var task))
{
2025-04-14 13:52:04 +08:00
Console.WriteLine("存在可下载任务,正在申请许可...");
await _semaphore.WaitAsync();
Console.WriteLine("申请下载许可成功!马上开启下载");
2025-04-12 15:50:38 +08:00
// 启动新线程执行下载任务
2025-04-12 16:24:15 +08:00
// _ = Task.Run(() => ExecuteTaskAsync(task));
_ = ExecuteTaskAsync(task).ContinueWith(_ => _semaphore.Release());
}
2025-04-14 13:52:04 +08:00
// 无任务时,进入低功耗轮询
Thread.Sleep(500);
}
}
public void AddTask(string bucketName, string objectKey, string size, string downDir)
{
var task = new MinioDownloadTask(_minioService, bucketName, objectKey, downDir, size);
2025-04-12 13:23:12 +08:00
using var client = SqlSugarConfig.GetSqlSugarScope();
client.Insertable(task).ExecuteCommandIdentityIntoEntity();
Application.Current.Dispatcher.Invoke(() =>
{
RunningTasks.Add(task);
RefreshHeader();
});
Console.WriteLine($"文件大小:{size} ");
_taskQueue.Enqueue(task);
}
private async Task ExecuteTaskAsync(MinioDownloadTask task)
{
try
{
// minio中好像自带重试机制
// 补充
if (task.Minio == null)
{
task.Minio = _minioService;
}
2025-04-12 13:23:12 +08:00
await task.StartDownload();
Application.Current.Dispatcher.Invoke(() =>
{
RunningTasks.Remove(task);
FinishedTasks.Add(task);
RefreshHeader();
});
}catch (Exception ex)
{
Console.WriteLine($"下载失败:{ex.Message}");
}
finally
{
}
}
private void AdjustConcurrency()
{
2025-04-12 15:50:38 +08:00
lock (_semaphore)
{
// 调整信号量容量
2025-04-12 15:50:38 +08:00
var delta = _maxConcurrent - _semaphore.CurrentCount;
if (delta > 0)
{
for (int i = 0; i < delta; i++)
{
2025-04-12 15:50:38 +08:00
_semaphore.Release();
}
}
}
}
2025-04-12 13:23:12 +08:00
public void DoOpenDownItemFolder(MinioDownloadTask para)
{
2025-04-12 13:23:12 +08:00
Console.WriteLine($"点击item值{JsonConvert.SerializeObject(para)}");
//Process.Start("explorer.exe", para.FilePath);
var file = Path.Combine(para.FilePath, para.FileName);
Process.Start("explorer.exe", $"/select,\"{file}\"");
}
2025-04-12 13:23:12 +08:00
public void DoCancelDownItem(MinioDownloadTask item)
{
2025-04-12 13:23:12 +08:00
Console.WriteLine("取消下载");
// todo 实现取消下载
}
2025-04-12 13:23:12 +08:00
public void DoPauseDownItem(MinioDownloadTask item)
{
2025-04-12 13:23:12 +08:00
Console.WriteLine("暂停下载");
// todo 实现暂停下载
2025-04-08 16:22:25 +08:00
}
protected override void Init()
{
}
protected override void Loaded(string args)
{
}
}