FieldWorkClient/ViewModel/Send/DownViewModel.cs

261 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)
{
}
}