using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using BetterGenshinImpact.Model.Gear.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using Microsoft.Extensions.Logging; namespace BetterGenshinImpact.Service; /// /// 任务执行状态 /// public enum TaskExecutionStatus { /// /// 等待执行 /// Pending, /// /// 正在执行 /// Running, /// /// 执行完成 /// Completed, /// /// 执行失败 /// Failed, /// /// 已取消 /// Cancelled, /// /// 已跳过 /// Skipped } /// /// 任务执行信息 /// public partial class TaskExecutionInfo : ObservableObject { [ObservableProperty] private string _taskName = string.Empty; [ObservableProperty] private string _taskType = string.Empty; [ObservableProperty] private TaskExecutionStatus _status = TaskExecutionStatus.Pending; [ObservableProperty] private DateTime _startTime; [ObservableProperty] private DateTime _endTime; [ObservableProperty] private TimeSpan _duration; [ObservableProperty] private string _errorMessage = string.Empty; [ObservableProperty] private double _progress; [ObservableProperty] private string _statusMessage = string.Empty; public BaseGearTask? Task { get; set; } public List Children { get; set; } = new(); public TaskExecutionInfo? Parent { get; set; } } /// /// 齿轮任务执行管理器,负责管理任务执行状态和进度跟踪 /// public partial class GearTaskExecutionManager : ObservableObject { private readonly ILogger _logger; private readonly Dictionary _taskInfoMap = new(); private CancellationTokenSource? _cancellationTokenSource; [ObservableProperty] private TaskExecutionInfo? _rootTaskInfo; [ObservableProperty] private TaskExecutionInfo? _currentTaskInfo; [ObservableProperty] private bool _isExecuting; [ObservableProperty] private double _overallProgress; [ObservableProperty] private string _overallStatusMessage = string.Empty; [ObservableProperty] private int _totalTasks; [ObservableProperty] private int _completedTasks; [ObservableProperty] private int _failedTasks; [ObservableProperty] private int _skippedTasks; public event EventHandler? TaskStarted; public event EventHandler? TaskCompleted; public event EventHandler? TaskFailed; public event EventHandler? TaskSkipped; public event EventHandler? ProgressChanged; public GearTaskExecutionManager(ILogger logger) { _logger = logger; } /// /// 开始执行任务并跟踪状态 /// /// 根任务 /// 取消令牌 /// public async Task ExecuteWithTrackingAsync(BaseGearTask rootTask, CancellationToken ct = default) { if (IsExecuting) { throw new InvalidOperationException("任务执行管理器正在运行中"); } try { IsExecuting = true; _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ct); // 初始化执行信息 InitializeExecutionInfo(rootTask); // 开始执行 await ExecuteTaskWithTrackingAsync(rootTask, _cancellationTokenSource.Token); // 更新最终状态 UpdateOverallStatus(); } catch (OperationCanceledException) { _logger.LogInformation("任务执行已取消"); OverallStatusMessage = "任务执行已取消"; throw; } catch (Exception ex) { _logger.LogError(ex, "任务执行过程中发生错误"); OverallStatusMessage = $"任务执行失败: {ex.Message}"; throw; } finally { IsExecuting = false; _cancellationTokenSource?.Dispose(); _cancellationTokenSource = null; } } /// /// 取消任务执行 /// public void CancelExecution() { if (IsExecuting && _cancellationTokenSource != null) { _logger.LogInformation("用户请求取消任务执行"); _cancellationTokenSource.Cancel(); OverallStatusMessage = "正在取消任务执行..."; } } /// /// 初始化执行信息 /// /// 根任务 private void InitializeExecutionInfo(BaseGearTask rootTask) { _taskInfoMap.Clear(); CompletedTasks = 0; FailedTasks = 0; SkippedTasks = 0; OverallProgress = 0; RootTaskInfo = CreateTaskExecutionInfo(rootTask); TotalTasks = CountTotalTasks(rootTask); OverallStatusMessage = "准备执行任务..."; _logger.LogInformation("初始化任务执行跟踪,总任务数: {TotalTasks}", TotalTasks); } /// /// 创建任务执行信息 /// /// 任务 /// 父任务信息 /// private TaskExecutionInfo CreateTaskExecutionInfo(BaseGearTask task, TaskExecutionInfo? parent = null) { var info = new TaskExecutionInfo { TaskName = task.Name, TaskType = task.Type, Status = TaskExecutionStatus.Pending, Task = task, Parent = parent }; _taskInfoMap[task] = info; // 递归创建子任务信息 if (task.Children?.Count > 0) { foreach (var child in task.Children) { var childInfo = CreateTaskExecutionInfo(child, info); info.Children.Add(childInfo); } } return info; } /// /// 执行任务并跟踪状态 /// /// 要执行的任务 /// 取消令牌 /// private async Task ExecuteTaskWithTrackingAsync(BaseGearTask task, CancellationToken ct) { if (!_taskInfoMap.TryGetValue(task, out var taskInfo)) { _logger.LogWarning("未找到任务执行信息: {TaskName}", task.Name); return; } CurrentTaskInfo = taskInfo; // 检查任务是否启用 if (!task.Enabled) { await MarkTaskSkipped(taskInfo, "任务已禁用"); return; } try { // 开始执行任务 await StartTask(taskInfo); // 执行当前任务 await task.Execute(ct); // 执行子任务 if (task.Children?.Count > 0) { for (int i = 0; i < task.Children.Count; i++) { var child = task.Children[i]; await ExecuteTaskWithTrackingAsync(child, ct); // 更新进度 var childProgress = (double)(i + 1) / task.Children.Count * 100; taskInfo.Progress = childProgress; UpdateOverallProgress(); } } // 完成任务 await CompleteTask(taskInfo); } catch (OperationCanceledException) { await MarkTaskCancelled(taskInfo); throw; } catch (Exception ex) { await FailTask(taskInfo, ex); throw; } } /// /// 开始执行任务 /// /// 任务信息 private async Task StartTask(TaskExecutionInfo taskInfo) { taskInfo.Status = TaskExecutionStatus.Running; taskInfo.StartTime = DateTime.Now; taskInfo.StatusMessage = "正在执行..."; _logger.LogInformation("开始执行任务: {TaskName}", taskInfo.TaskName); TaskStarted?.Invoke(this, taskInfo); await Task.CompletedTask; } /// /// 完成任务 /// /// 任务信息 private async Task CompleteTask(TaskExecutionInfo taskInfo) { taskInfo.Status = TaskExecutionStatus.Completed; taskInfo.EndTime = DateTime.Now; taskInfo.Duration = taskInfo.EndTime - taskInfo.StartTime; taskInfo.Progress = 100; taskInfo.StatusMessage = "执行完成"; CompletedTasks++; _logger.LogInformation("任务执行完成: {TaskName}, 耗时: {Duration}ms", taskInfo.TaskName, taskInfo.Duration.TotalMilliseconds); TaskCompleted?.Invoke(this, taskInfo); UpdateOverallProgress(); await Task.CompletedTask; } /// /// 任务执行失败 /// /// 任务信息 /// 异常 private async Task FailTask(TaskExecutionInfo taskInfo, Exception exception) { taskInfo.Status = TaskExecutionStatus.Failed; taskInfo.EndTime = DateTime.Now; taskInfo.Duration = taskInfo.EndTime - taskInfo.StartTime; taskInfo.ErrorMessage = exception.Message; taskInfo.StatusMessage = $"执行失败: {exception.Message}"; FailedTasks++; _logger.LogError(exception, "任务执行失败: {TaskName}", taskInfo.TaskName); TaskFailed?.Invoke(this, taskInfo); UpdateOverallProgress(); await Task.CompletedTask; } /// /// 标记任务为已跳过 /// /// 任务信息 /// 跳过原因 private async Task MarkTaskSkipped(TaskExecutionInfo taskInfo, string reason) { taskInfo.Status = TaskExecutionStatus.Skipped; taskInfo.StatusMessage = $"已跳过: {reason}"; SkippedTasks++; _logger.LogInformation("任务已跳过: {TaskName}, 原因: {Reason}", taskInfo.TaskName, reason); TaskSkipped?.Invoke(this, taskInfo); UpdateOverallProgress(); await Task.CompletedTask; } /// /// 标记任务为已取消 /// /// 任务信息 private async Task MarkTaskCancelled(TaskExecutionInfo taskInfo) { taskInfo.Status = TaskExecutionStatus.Cancelled; taskInfo.EndTime = DateTime.Now; taskInfo.Duration = taskInfo.EndTime - taskInfo.StartTime; taskInfo.StatusMessage = "已取消"; _logger.LogInformation("任务已取消: {TaskName}", taskInfo.TaskName); await Task.CompletedTask; } /// /// 更新整体进度 /// private void UpdateOverallProgress() { if (TotalTasks > 0) { var processedTasks = CompletedTasks + FailedTasks + SkippedTasks; OverallProgress = (double)processedTasks / TotalTasks * 100; OverallStatusMessage = $"进度: {processedTasks}/{TotalTasks} (完成: {CompletedTasks}, 失败: {FailedTasks}, 跳过: {SkippedTasks})"; ProgressChanged?.Invoke(this, OverallProgress); } } /// /// 更新最终状态 /// private void UpdateOverallStatus() { if (FailedTasks > 0) { OverallStatusMessage = $"执行完成,但有 {FailedTasks} 个任务失败"; } else if (SkippedTasks > 0) { OverallStatusMessage = $"执行完成,跳过了 {SkippedTasks} 个任务"; } else { OverallStatusMessage = "所有任务执行完成"; } } /// /// 统计任务总数 /// /// 根任务 /// 任务总数 private int CountTotalTasks(BaseGearTask task) { int count = 1; if (task.Children?.Count > 0) { foreach (var child in task.Children) { count += CountTotalTasks(child); } } return count; } /// /// 获取任务执行统计信息 /// /// 统计信息 public TaskExecutionStatistics GetStatistics() { return new TaskExecutionStatistics { TotalTasks = TotalTasks, CompletedTasks = CompletedTasks, FailedTasks = FailedTasks, SkippedTasks = SkippedTasks, OverallProgress = OverallProgress, IsExecuting = IsExecuting }; } } /// /// 任务执行统计信息 /// public class TaskExecutionStatistics { public int TotalTasks { get; set; } public int CompletedTasks { get; set; } public int FailedTasks { get; set; } public int SkippedTasks { get; set; } public double OverallProgress { get; set; } public bool IsExecuting { get; set; } public int ProcessedTasks => CompletedTasks + FailedTasks + SkippedTasks; public double SuccessRate => TotalTasks > 0 ? (double)CompletedTasks / TotalTasks * 100 : 0; }