using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using PCL.Core.Logging;
namespace PCL.Core.App.Tasks;
///
/// 任务中心,用于管理任务
///
public static class TaskCenter
{
///
/// 可观察的任务模型集合
///
public static ObservableCollection Tasks { get; } = [];
private static readonly ConditionalWeakTable _ModelMap = [];
private static TaskModel _InitModel(ITask instance)
{
// ReSharper disable SuspiciousTypeConversion.Global
var cancelable = instance as ITaskCancelable;
var pausable = instance as ITaskPausable;
var progressive = instance as ITaskProgressive;
// ReSharper restore SuspiciousTypeConversion.Global
var model = new TaskModel
{
Title = instance.Title,
SupportProgress = progressive is not null,
OnCancel = cancelable is null ? null : (() => cancelable.Cancel()),
OnPause = pausable is null ? null : (() => pausable.Pause()),
};
// state event
instance.StateChanged += (state, message) =>
{
LogWrapper.Trace("TaskCenter", $"{instance.Title}: state changed ({state}): {message}");
model.State = state;
model.StateMessage = message;
};
// progress event
if (progressive is not null)
{
progressive.ProgressChanged += progress =>
{
model.Progress = Math.Clamp(progress, 0.0, 1.0);
};
}
// group events
if (instance is ITaskGroup group)
{
group.AddTask += task =>
{
var taskModel = _InitModel(task);
_ModelMap.Add(task, taskModel);
model.Children.Add(taskModel);
};
group.RemoveTask += task =>
{
if (_ModelMap.TryGetValue(task, out var taskModel)) model.Children.Remove(taskModel);
};
}
return model;
}
///
/// 注册响应式任务实例
///
/// 任务实例
/// 是否立即启动该实例
public static void Register(ITask instance, bool start = true)
{
var model = _InitModel(instance);
Tasks.Add(model);
if (start)
{
_ = Task.Run(async () =>
{
try { await instance.ExecuteAsync(); }
catch (OperationCanceledException) { /* ignoring */ }
catch (Exception ex)
{
LogWrapper.Warn(ex, "TaskCenter", $"{instance.Title}: exception thrown");
model.State = TaskState.Failed;
model.StateMessage = ex.Message;
}
});
}
}
///
/// 移除所有已结束的任务
///
public static void RemoveFinished()
{
foreach (var model in Tasks.Where(x => x.State > TaskState.Running).ToList())
Tasks.Remove(model);
}
}