using System.Collections.Concurrent; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; 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; using SqlSugar; namespace Hopetry.ViewModel.Send; [ViewModel("Down")] public class DownViewModel : MvcViewModelBase { private readonly MinioService _minioService; public RelayCommand OpenDownItemFolder { get; set; } private readonly ConcurrentQueue _taskQueue = new(); private SemaphoreSlim _concurrencySemaphore; private CancellationTokenSource _processingCts = new(); public int count { get; set; } private SemaphoreSlim _semaphore; private readonly ReaderWriterLockSlim _lock = new(); /// /// 全部任务动态标题 /// 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 AllTasks { get; set; } = new(); 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; } /// /// 构造函数 /// /// public DownViewModel(MinioService minioService, SemaphoreSlim semaphore) { _minioService = minioService; _semaphore = semaphore; Console.WriteLine("初始化DownViewModel"); using var client = SqlSugarConfig.GetSqlSugarScope(); var data = client.Ado.SqlQuery($"select * from download_task"); //DownItems = new ObservableCollection(data); AllTasks = new ObservableCollection(data); AllTaskHeader = $"全部({AllTasks.Count})"; //Console.WriteLine(JsonConvert.SerializeObject(data)); OpenDownItemFolder = new RelayCommand(DoOpenDownItemFolder); // 命令初始化 // AddTaskCommand = new RelayCommand(AddTask, CanAddTask); // 修正:使用 CollectionViewSource 确保通知 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; if (FinishedTasksView is ListCollectionView finishListView) { FinishedTaskHeader = $"已完成({finishListView.Count})"; } if (RunningTasksView is ListCollectionView runningListView) { RunningTaskHeader = $"下载中({runningListView.Count})"; } // 关键:订阅数据源变更事件,强制视图刷新 AllTasks.CollectionChanged += (s, e) => { RunningTasksView.Refresh(); FinishedTasksView.Refresh(); }; ClearFinishedCommand = new CustomCommand(() => { // todo 删除已完成的下载记录 }); // 启动任务处理线程 _semaphore = new SemaphoreSlim(_maxConcurrent); // 启动任务处理线程 _concurrencySemaphore = new SemaphoreSlim(_maxConcurrent); new Thread(ProcessTasksLoop) { IsBackground = true }.Start(); AddTaskCommand = new ActionCommand(AddTask); } private void ProcessTasksLoop() { while (!_processingCts.IsCancellationRequested) { _semaphore.WaitAsync(); // 按当前并发数启动任务 for (int i = 0; i < _maxConcurrent; i++) { if (_taskQueue.TryDequeue(out var task)) { // 启动新线程执行下载任务 _ = Task.Run(() => ExecuteTaskAsync(task)); } } Thread.Sleep(100); } } private void AddTask() { string[] objectKeys = { "demo/06.mp4", "demo/07.mp4", "demo/08.mp4", "demo/10.mp4" }; var task = new MinioDownloadTask(_minioService, "demo", objectKeys[count++]); using var client = SqlSugarConfig.GetSqlSugarScope(); client.Insertable(task).ExecuteCommandIdentityIntoEntity(); AllTasks.Add(task); _taskQueue.Enqueue(task); } private async Task ExecuteTaskAsync(MinioDownloadTask task) { try { await task.StartDownload(); // todo 任务完成下载 } finally { _semaphore.Release(); } } private void AdjustConcurrency() { lock (_concurrencySemaphore) { // 调整信号量容量 var delta = _maxConcurrent - _concurrencySemaphore.CurrentCount; if (delta > 0) { for (int i = 0; i < delta; i++) { _concurrencySemaphore.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) { } }