FieldWorkClient/ViewModel/Send/SendViewModel.cs

927 lines
33 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;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Net.Http;
using System.Security.AccessControl;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Threading;
using HeBianGu.Base.WpfBase;
using HeBianGu.General.WpfControlLib;
using HeBianGu.Service.Mvc;
using Hopetry.Provider;
using Hopetry.Provider.Behaviors;
using Hopetry.Services;
using Hopetry.ViewModel.Send;
using Microsoft.Extensions.Configuration;
using Minio.DataModel.Args;
using Minio.DataModel;
using Minio;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Timers;
using Hopetry.Services;
namespace HeBianGu.App.Disk
{
[ViewModel("Send")]
internal class SendViewModel : MvcViewModelBase
{
private LinkAction _uploadingAction; //正在上传
private LinkAction _completeAction; //上传完成
public LinkAction DownLinkAction;
public LinkAction _waituploadAction;
private readonly FileUploadService _uploadService;
public ICommand WaitUpLoadCommand { get; }
public ICommand DeleteWaitUpLoadCommand { get; }
public bool _isUploading = false;
public string CurrentMinIOPath;
// 分页相关字段
private int _waitUploadCurrentPage = 1;
private int _completedCurrentPage = 1;
private const int PAGE_SIZE = 50;
// 上传完成事件
public event Action<string> FileUploadCompleted;
public SendViewModel()
{
_uploadService = new FileUploadService();
// 初始化Timer
_progressTimer = new System.Timers.Timer(1000);
_progressTimer.Elapsed += UpdateProgress;
_heartbeatTimer = new System.Timers.Timer(30_000);
//_heartbeatTimer.Elapsed += async (s, e) => await SendHeartbeatAsync();
DeleteWaitUpLoadCommand = new AsyncRelayCommand(async () => await DeleteFile());
WaitUpLoadCommand = new AsyncRelayCommand(async () => await UploadWaitItems());
systemInfo = SystemInfoCollector.Collect();
//加载待上传列表
GetWaitUploadItems(1); // 从第一页开始加载
//加载上传完成列表
GetCompletedFiles(1); // 从第一页开始加载
//new Thread(ProcessUploadTasks) { IsBackground = true }.Start();
Task.Run(() => ProcessUploadTasks()); // 启动文件上传线程
}
protected override void Init()
{
ITransitionWipe wipe = new CircleWipe();
DownLinkAction = new LinkAction()
{ Action = "Down", Controller = "Send", DisplayName = "下载 0", Logo = "\xe891", TransitionWipe = wipe };
LinkActions.Add(DownLinkAction);
// 正在上传
_uploadingAction = new LinkAction()
{
Action = "UpLoad",
Controller = "Send",
DisplayName = "正在上传",
Logo = "\xe6f3",
TransitionWipe = wipe
};
LinkActions.Add(_uploadingAction);
_completeAction = new LinkAction()
{
Action = "CompleteUpload",
Controller = "Send",
DisplayName = "上传完成",
Logo = "\xe613",
TransitionWipe = wipe
};
LinkActions.Add(_completeAction);
_waituploadAction = new LinkAction()
{
Action = "WaitUpload",
Controller = "Send",
DisplayName = "待上传",
Logo = "\xe613",
TransitionWipe = wipe
};
LinkActions.Add(_waituploadAction);
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Loaded,
new Action(() => { SelectLink = LinkActions[0]; }));
UpLoadItems.CollectionChanged += (s, e) => { UpdateUploadingItems(); };
}
protected override void Loaded(string args)
{
}
#region 文件上传
#region 参数
//上传文件总数
private ObservableCollection<UpLoadItems> _upLoadItems = new ObservableCollection<UpLoadItems>();
/// <summary> 说明 </summary>
public ObservableCollection<UpLoadItems> UpLoadItems
{
get { return _upLoadItems; }
set
{
_upLoadItems = value;
//UpdateUploadingItems();
RaisePropertyChanged("UpLoadItems");
}
}
//已上传完成文件
private ObservableCollection<UpLoadItems> _completeItems = new ObservableCollection<UpLoadItems>();
public ObservableCollection<UpLoadItems> CompleteItems
{
get { return _completeItems; }
private set
{
_completeItems = value;
RaisePropertyChanged("CompleteItems");
}
}
//待上传文件
private ObservableCollection<UpLoadItems> _waitUpLoadItems = new ObservableCollection<UpLoadItems>();
/// <summary> 说明 </summary>
public ObservableCollection<UpLoadItems> WaitUpLoadItems
{
get { return _waitUpLoadItems; }
set
{
_waitUpLoadItems = value;
RaisePropertyChanged("WaitUpLoadItems");
}
}
private bool? _isAllSelected;
public bool? IsAllSelected
{
get => _isAllSelected;
set
{
_isAllSelected = value;
// 全选/取消全选逻辑
if (value.HasValue)
{
foreach (var item in WaitUpLoadItems)
{
item.IsSelect = value.Value;
}
}
}
}
// 只读属性,返回过滤后的集合(动态计算)
private ObservableCollection<UpLoadItems> _uploadingItems = new ObservableCollection<UpLoadItems>();
public ObservableCollection<UpLoadItems> UploadingItems
{
get { return _uploadingItems; }
private set
{
_uploadingItems = value;
RaisePropertyChanged("UploadingItems");
}
}
// 在 UpLoadItems 变化时更新 UploadingItems
public void UpdateUploadingItems()
{
UploadingItems = new ObservableCollection<UpLoadItems>(
UpLoadItems?.Where(item => item.Value3 != "已完成") ?? Enumerable.Empty<UpLoadItems>()
);
}
//文件上传进度
private decimal _progress;
public decimal Progress
{
get { return _progress; }
set
{
if (_progress != value)
{
_progress = value;
RaisePropertyChanged("Progress");
}
}
}
//上传文件个数
private string _filecount;
public string FileCount
{
get { return _filecount; }
set
{
if (_filecount != value)
{
_filecount = value;
RaisePropertyChanged("FileCount");
}
}
}
//上传完成文件个数
private int _uploadingcount;
public int UploadingCount
{
get { return _uploadingcount; }
set
{
if (_uploadingcount != value)
{
_uploadingcount = value;
_uploadingAction.FullName = "(" + _uploadingcount + ")";
RaisePropertyChanged("UploadingCount");
}
}
}
//上传文件个数
private int _completecount;
public int CompleteCount
{
get { return _completecount; }
set
{
if (_completecount != value)
{
_completecount = value;
_completeAction.FullName = "(" + _completecount + ")";
RaisePropertyChanged("CompleteCount");
}
}
}
// 内存使用监控
private long _lastMemoryUsage = GC.GetTotalMemory(false);
public long MemoryUsage
{
get { return GC.GetTotalMemory(false); }
}
public double MemoryUsageMB
{
get { return Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0, 2); }
}
//等待上传文件个数
private int _waitcount;
public int WaitCount
{
get { return _waitcount; }
set
{
if (_waitcount != value)
{
_waitcount = value;
_waituploadAction.FullName = "(" + _waitcount + ")";
RaisePropertyChanged("WaitCount");
}
}
}
#endregion
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#endregion
#region 删除等待上传文件
private async Task DeleteFile()
{
try
{
var items = WaitUpLoadItems.Where(r => r.IsSelect == true).ToList();
if (items == null || !items.Any())
{
await MessageProxy.Messager.ShowResult("请先选择要删除的项目");
return;
}
var message = $"确定要删除选中的 {items.Count} 个项目吗?";
var result = MessageBox.Show(message, "确认删除", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
List<string> list = new List<string>();
list = items.Select(r => r.Value4).ToList();
var flag = _uploadService.DeleteFiles(list);
WaitUpLoadItems.RemoveAll(r => r.IsSelect == true);
WaitCount = WaitUpLoadItems.Count;
if (flag == true)
{
MessageBox.Show($"已成功删除 {items.Count} 个项目");
IsAllSelected = false;
}
else
{
MessageBox.Show($"删除失败");
}
}
}
catch (Exception ex)
{
MessageBox.Show($"删除失败: {ex.Message}");
}
}
#endregion
#region 上传待上传文件
public async Task UploadWaitItems()
{
var items = WaitUpLoadItems.Where(r => r.IsSelect == true).ToList();
try
{
foreach (var item in items)
{
FileInfo fileInfo = new FileInfo(item.Value5);
string sizeText = fileInfo.Length < 1024 * 1024
? $"{Math.Ceiling((decimal)fileInfo.Length / 1024)}KB"
: $"{Math.Ceiling((decimal)fileInfo.Length / (1024 * 1024))}MB";
UpLoadItems ut = new UpLoadItems();
ut.Value = item.Value;
ut.Value3 = "等待上传";
ut.Value4 = item.Value4; //唯一标识,与数据库一致
ut.Value5 = item.Value5; //文件名称
ut.Value6 = item.Value6; //文件地址
ut.Value9 = item.Value9;
ut.Double1 = fileInfo.Length;
ut.Double2 = 0.0;
ut.Bool1 = false;
ut.Value1 = $"0{(fileInfo.Length < 1024 * 1024 ? "KB" : "MB")}/{sizeText}";
UpLoadItems.Add(ut);
}
_uploadCount = UpLoadItems.Count;
_completeCount = UpLoadItems.Where(r => r.Value3 == "已完成").Count();
FileCount = (CompleteItems.Count) + "/" + (UpLoadItems.Count + CompleteItems.Count);
UploadingCount = UploadingItems.Count;
CompleteCount = CompleteItems.Count;
MessageBox.Show("正在上传列表中可查看进度");
WaitUpLoadItems.RemoveAll(r => r.IsSelect == true);
IsAllSelected = false;
WaitCount = WaitUpLoadItems.Count;
// 如果没有上传任务在运行,则启动上传
if (!_isUploading)
{
try
{
await ProcessUploadTasks();
}
catch
{
MessageBox.Show("上传失败");
}
}
}
catch (Exception ex)
{
MessageBox.Show("文件丢失");
}
}
#endregion
#region 获取等待上传列表
public void GetWaitUploadItems(int pageNumber = 1)
{
var waitlist = _uploadService.GetIncompleteFiles(pageNumber, PAGE_SIZE);
ObservableCollection<UpLoadItems> up = new ObservableCollection<UpLoadItems>();
if (_isUploading == false)
{
foreach (var file in waitlist)
{
UpLoadItems upLoadItems = new UpLoadItems();
upLoadItems.Value = file.FileName;
upLoadItems.Value4 = file.Id;
upLoadItems.Value5 = file.FilePath;
upLoadItems.Value1 = file.FileSizeText;
upLoadItems.Value6 = file.FileName;
upLoadItems.Value7 = file.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
upLoadItems.Value9 = file.BucketName;
upLoadItems.Bool1 = false;
up.Add(upLoadItems);
}
WaitUpLoadItems.Clear();
WaitUpLoadItems.AddRange(up);
WaitCount = _uploadService.GetIncompleteFileCount(); // 从数据库获取总数
}
}
#endregion
#region 加载上传完成列表
//加载初始完成文件
public void GetCompletedFiles(int pageNumber = 1)
{
var files = _uploadService.GetCompleteFiles(pageNumber, PAGE_SIZE);
ObservableCollection<UpLoadItems> up = new ObservableCollection<UpLoadItems>();
foreach (var file in files)
{
UpLoadItems upLoadItems = new UpLoadItems();
upLoadItems.Value = file.FileName;
upLoadItems.Value4 = file.Id;
upLoadItems.Value5 = file.FilePath;
upLoadItems.Value1 = file.FileSizeText;
upLoadItems.Value6 = file.FileName;
upLoadItems.Value7 = file.CompleteTime.ToString("yyyy-MM-dd HH:mm:ss");
upLoadItems.Value9 = file.BucketName;
up.Add(upLoadItems);
}
CompleteItems.Clear();
CompleteItems.AddRange(up);
regionCount = _uploadService.GetCompleteFileCount(); // 从数据库获取总数
CompleteCount = regionCount;
}
// 加载更多待上传文件
public void LoadMoreWaitUploadItems()
{
_waitUploadCurrentPage++;
var waitlist = _uploadService.GetIncompleteFiles(_waitUploadCurrentPage, PAGE_SIZE);
if (waitlist.Count > 0)
{
foreach (var file in waitlist)
{
UpLoadItems upLoadItems = new UpLoadItems();
upLoadItems.Value = file.FileName;
upLoadItems.Value4 = file.Id;
upLoadItems.Value5 = file.FilePath;
upLoadItems.Value1 = file.FileSizeText;
upLoadItems.Value6 = file.FileName;
upLoadItems.Value7 = file.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
upLoadItems.Value9 = file.BucketName;
upLoadItems.Bool1 = false;
WaitUpLoadItems.Add(upLoadItems);
}
WaitCount = _uploadService.GetIncompleteFileCount();
}
}
// 加载更多已完成文件
public void LoadMoreCompletedItems()
{
_completedCurrentPage++;
var files = _uploadService.GetCompleteFiles(_completedCurrentPage, PAGE_SIZE);
if (files.Count > 0)
{
foreach (var file in files)
{
UpLoadItems upLoadItems = new UpLoadItems();
upLoadItems.Value = file.FileName;
upLoadItems.Value4 = file.Id;
upLoadItems.Value5 = file.FilePath;
upLoadItems.Value1 = file.FileSizeText;
upLoadItems.Value6 = file.FileName;
upLoadItems.Value7 = file.CompleteTime.ToString("yyyy-MM-dd HH:mm:ss");
upLoadItems.Value9 = file.BucketName;
CompleteItems.Add(upLoadItems);
}
regionCount = _uploadService.GetCompleteFileCount();
CompleteCount = regionCount;
}
}
#endregion
#region 上传
//private SendViewModel _sendViewModel;
private SemaphoreSlim _semaphore = new SemaphoreSlim(5);
private System.Timers.Timer _progressTimer;
private System.Timers.Timer _heartbeatTimer;
private bool _isTimerRunning = false;
private object _timerLock = new object();
private Task _currentUploadTask = null; // 新增:当前上传任务
private CancellationTokenSource _uploadCancellation = new();
public int _uploadCount = 0;
public int _completeCount = 0;
private int regionCount = 0;
private ExplorerMinIOBehavior _explorerBehavior;
private Hopetry.Provider.SystemInfo systemInfo;
// 配置Redis连接
//private RedisService redis = new RedisService("175.27.168.120:6050,password=HopetryRedis1406,connectRetry=3");
#region 更新总进度条 每隔1s更新一次
private DateTime _lastProgressUpdate = DateTime.MinValue;
private void UpdateProgress(object sender, ElapsedEventArgs e)
{
if (UpLoadItems.Count == 0) return;
var now = DateTime.Now;
/*// 限制进度更新频率
if ((now - _lastProgressUpdate).TotalMilliseconds < 500) // 至少500ms更新一次
{
return;
}
double currentBytes = UpLoadItems.Sum(r => r.Double2);
double totalBytes = UpLoadItems.Sum(r => r.Double1);*/
FileCount = (CompleteItems.Count) + "/" + (UpLoadItems.Count + CompleteItems.Count);
// 避免除零错误
var progress = UpLoadItems.Count > 0
? Math.Round((decimal)(CompleteItems.Count / (UpLoadItems.Count + CompleteItems.Count)) * 100, 2)
: 0;
Application.Current.Dispatcher.Invoke(() =>
{
Progress = progress;
_lastProgressUpdate = now;
});
}
//上传redis心跳检测
//private async Task SendHeartbeatAsync()
//{
// try
// {
// // 上报心跳并更新客户端信息
// //await redis.StoreClientInfoAsync(systemInfo);
// await redis.UpdateClientHeartbeatAsync(systemInfo.MachineId);
// }
// catch (Exception ex)
// {
// // 处理网络异常等
// Debug.WriteLine($"心跳上报失败: {ex.Message}");
// }
//}
private void StartProgressTimer()
{
lock (_timerLock)
{
if (!_isTimerRunning)
{
_progressTimer.Start();
_heartbeatTimer.Start();
_isTimerRunning = true;
}
}
}
private void StopProgressTimer()
{
lock (_timerLock)
{
if (_isTimerRunning)
{
_progressTimer.Stop();
_heartbeatTimer.Stop();
_isTimerRunning = false;
}
}
}
#endregion
//创建上传任务
public async Task ProcessUploadTasks()
{
if (_isUploading) return; // 避免重复启动
_isUploading = true;
StartProgressTimer();
try
{
while (!_uploadCancellation.Token.IsCancellationRequested)
{
// 在后台线程获取待处理项
var pendingItems = UpLoadItems.Where(r => !r.Bool1).ToList();
if (!pendingItems.Any())
Thread.Sleep(500);
// 分批处理,避免一次性启动过多任务
const int batchSize = 10;
for (int i = 0; i < pendingItems.Count; i += batchSize)
{
var batch = pendingItems.Skip(i).Take(batchSize).ToList();
//创建并运行上传任务
var batchTasks = batch.Select(async item =>
{
// 使用带超时的信号量等待
if (await _semaphore.WaitAsync(30000, _uploadCancellation.Token)) // 30秒超时
{
try
{
await UploadFileToMinIOWithProgress(item);
}
finally
{
_semaphore.Release();
}
}
else
{
// 信号量获取超时,标记为失败
await Application.Current.Dispatcher.BeginInvoke(() =>
{
item.Value3 = "上传超时";
_uploadService.UpdateFileComplete(item.Value4.ToString(), false);
});
}
});
await Task.WhenAll(batchTasks);
// 批次间短暂延迟,避免过度占用资源
await Task.Delay(100);
}
}
}
catch (OperationCanceledException)
{
// 正常取消操作
Console.WriteLine("上传任务被取消");
}
catch (Exception ex)
{
Console.WriteLine($"上传任务异常: {ex.Message}");
// 上传被取消
}
finally
{
await Task.Delay(1000);
StopProgressTimer();
_isUploading = false;
// 在UI线程上更新界面
await Application.Current.Dispatcher.BeginInvoke(() =>
{
UpLoadItems.Clear();
//加载上传完成列表
GetCompletedFiles(1); // 重新加载第一页
if (MySetting.Instance.IsOn && !UpLoadItems.Any(item => !item.Bool1))
{
Shutdown();
}
// 刷新网盘空间页面以显示新上传的文件
//_explorerBehavior?.RefreshMinIOPath(CurrentMinIOPath);
// 执行垃圾回收以释放内存
GC.Collect();
GC.WaitForPendingFinalizers();
});
}
}
//上传具体执行
private async Task UploadFileToMinIOWithProgress(UpLoadItems ut)
{
ut.Bool1 = true;
try
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("global.json", optional: false, reloadOnChange: true);
// 构建配置
var config = builder.Build();
// 获取滑块设置的速度限制(转换为字节 / 秒)
// 查询所有客户端
//var allClients = await redis.GetAllClientsAsync();
//var num = allClients == null ? 1 : allClients.Distinct().Count();
//var speedLimit = 10 * 1024 * 1024 / num/5;
var speedLimit = 100 * 1024 * 1024;
//var speedLimit = Convert.ToInt64(config["Minio:limitspeed"]);
var handler = new MinIOThrottledHandler(speedLimit,
new HttpClientHandler
{
// 保持 MinIO 必需的 SSL 配置
ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) => true
});
//var handler =
// new HttpClientHandler
// {
// // 保持 MinIO 必需的 SSL 配置
// ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) => true
// };
// 从配置获取MinIO设置更安全
IMinioClient client = new MinioClient()
.WithEndpoint(config["Minio:Endpoint"])
.WithCredentials(config["Minio:AccessKey"], config["Minio:SecretKey"])
.WithHttpClient(new HttpClient() { Timeout = TimeSpan.FromMinutes(30) })
.Build();
//string bucketName = GetCurrentBucket();
string bucketName = ut.Value9;
if (string.IsNullOrEmpty(bucketName))
{
throw new Exception("桶不能为空");
}
// 确保桶存在
var beArgs = new BucketExistsArgs().WithBucket(bucketName);
bool found = await client.BucketExistsAsync(beArgs).ConfigureAwait(false);
if (!found)
{
var mbArgs = new MakeBucketArgs().WithBucket(bucketName);
await client.MakeBucketAsync(mbArgs).ConfigureAwait(false);
}
// 限制UI更新频率
DateTime lastUiUpdate = DateTime.MinValue;
var progress = new Progress<ProgressReport>(progressReport =>
{
var now = DateTime.Now;
// 限制UI更新频率每200ms最多更新一次
if ((now - lastUiUpdate).TotalMilliseconds > 200)
{
Application.Current.Dispatcher.InvokeAsync(() =>
{
ut.Int1 = progressReport.Percentage;
long trans = progressReport.TotalBytesTransferred;
ut.Double2 = trans;
int slashIndex = ut.Value1.IndexOf('/');
string sizePart = ut.Value1.Substring(slashIndex);
string transferredPart = trans < 1024 * 1024
? $"{Math.Ceiling((decimal)trans / 1024)}KB"
: $"{Math.Ceiling((decimal)trans / (1024 * 1024))}MB";
ut.Value1 = $"{transferredPart}{sizePart}";
ut.Value3 = progressReport.Percentage == 100 ? "验证中..." : "上传中...";
lastUiUpdate = now;
});
}
});
// 使用安全上传助手进行文件上传
bool uploadSuccess = await UploadHelper.SafeUploadFileAsync(
client,
bucketName,
ut.Value5,
ut.Value6,
progress);
if (!uploadSuccess)
{
throw new Exception("文件上传失败");
}
// 上传完成后进行验证
await UploadVerifier.VerifyAsync(client, bucketName, ut.Value6);
// 验证成功后更新状态
ut.Value7 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string id = ut.Value4.ToString();
await _uploadService.UpdateFileCompleteAsync(id, true);
// Application.Current.Dispatcher.Invoke
// 在UI线程上更新界面
await Application.Current.Dispatcher.BeginInvoke(() =>
{
// 从上传列表中移除已完成的项目
UpLoadItems.Remove(ut);
// 添加到完成列表
CompleteItems.Add(ut);
ut.Value3 = "已完成";
UpdateUploadingItems();
_completeCount++;
FileCount = (CompleteItems.Count) + "/" + (UpLoadItems.Count + CompleteItems.Count);
UpdateFileCounts();
// 刷新当前目录
//_explorerBehavior?.RefreshMinIOPath(CurrentMinIOPath);
// 触发上传完成事件
//FileUploadCompleted?.Invoke(CurrentMinIOPath);
Progress = (CompleteItems.Count) / (UpLoadItems.Count + CompleteItems.Count);
// 更新网盘空间页面状态
/*if (_explorerBehavior != null)
{
// 延迟刷新以确保MinIO有时间同步数据
Task.Delay(500).ContinueWith(_ =>
{
Application.Current.Dispatcher.Invoke(() =>
{
_explorerBehavior.RefreshMinIOPath(CurrentMinIOPath);
});
});
}*/
});
}
catch (Exception ex)
{
await Application.Current.Dispatcher.BeginInvoke(() => { ut.Value3 = $"上传失败: {ex.Message}"; });
try
{
await _uploadService.UpdateFileCompleteAsync(ut.Value4.ToString(), false);
}
catch (Exception dbEx)
{
Console.WriteLine($"数据库更新失败: {dbEx.Message}");
}
Console.WriteLine($"文件 {ut.Value} 上传失败: {ex.Message}");
}
}
//获取当前路径下的桶
private string GetCurrentBucket()
{
if (string.IsNullOrEmpty(CurrentMinIOPath))
return string.Empty;
return CurrentMinIOPath.Split('/')[0];
}
//更新上传进行中及上传完成列表
private void UpdateFileCounts()
{
UploadingCount = UploadingItems.Count;
CompleteCount = CompleteItems.Count;
}
public void AddUploadTask(UpLoadItems ut)
{
Application.Current.Dispatcher.BeginInvoke(() =>
{
UpLoadItems.Add(ut);
_uploadCount = UpLoadItems.Count;
_completeCount = UpLoadItems.Where(r => r.Value3 == "已完成").Count();
FileCount = (CompleteItems.Count) + "/" + (UpLoadItems.Count + CompleteItems.Count);
UpdateFileCounts();
});
}
//关机
private void Shutdown()
{
try
{
Process.Start("shutdown", "/s /t 0");
}
catch (Win32Exception ex)
{
MessageBox.Show($"关机失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
// 清理资源
public void Cleanup()
{
_progressTimer?.Stop();
_progressTimer?.Dispose();
_heartbeatTimer?.Stop();
_heartbeatTimer?.Dispose();
_semaphore?.Release();
_uploadCancellation?.Cancel();
_uploadCancellation?.Dispose();
// 清理集合以释放内存
UpLoadItems?.Clear();
CompleteItems?.Clear();
WaitUpLoadItems?.Clear();
}
#endregion
}
}