266 lines
7.9 KiB
C#
266 lines
7.9 KiB
C#
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using RevitHttpControl.Models;
|
||
|
||
namespace RevitHttpControl.Services
|
||
{
|
||
/// <summary>
|
||
/// 任务管理器
|
||
/// </summary>
|
||
public class TaskManager
|
||
{
|
||
private static readonly Lazy<TaskManager> _instance = new Lazy<TaskManager>(() => new TaskManager());
|
||
|
||
/// <summary>
|
||
/// 单例实例
|
||
/// </summary>
|
||
public static TaskManager Instance => _instance.Value;
|
||
|
||
/// <summary>
|
||
/// 任务状态存储
|
||
/// </summary>
|
||
private readonly ConcurrentDictionary<Guid, TaskStatusResponse> _tasks;
|
||
|
||
/// <summary>
|
||
/// 上次清理时间
|
||
/// </summary>
|
||
private DateTime _lastCleanupTime;
|
||
|
||
/// <summary>
|
||
/// 清理间隔(小时)
|
||
/// </summary>
|
||
private const int CLEANUP_INTERVAL_HOURS = 1;
|
||
|
||
/// <summary>
|
||
/// 私有构造函数
|
||
/// </summary>
|
||
private TaskManager()
|
||
{
|
||
_tasks = new ConcurrentDictionary<Guid, TaskStatusResponse>();
|
||
_lastCleanupTime = DateTime.UtcNow;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建新任务
|
||
/// </summary>
|
||
/// <returns>任务ID</returns>
|
||
public Guid CreateTask(string executionId = null)
|
||
{
|
||
// 检查是否需要清理过期任务
|
||
CheckAndCleanupIfNeeded();
|
||
|
||
var taskId = Guid.NewGuid();
|
||
var effectiveExecutionId = string.IsNullOrWhiteSpace(executionId)
|
||
? taskId.ToString()
|
||
: executionId;
|
||
var task = new TaskStatusResponse
|
||
{
|
||
TaskId = taskId,
|
||
Status = TaskStatus.Pending,
|
||
CreatedAt = DateTime.UtcNow,
|
||
ExecutionId = effectiveExecutionId
|
||
};
|
||
|
||
_tasks.TryAdd(taskId, task);
|
||
return taskId;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查并在需要时清理过期任务
|
||
/// </summary>
|
||
private void CheckAndCleanupIfNeeded()
|
||
{
|
||
var now = DateTime.UtcNow;
|
||
if (now.Subtract(_lastCleanupTime).TotalHours >= CLEANUP_INTERVAL_HOURS)
|
||
{
|
||
CleanupExpiredTasks();
|
||
_lastCleanupTime = now;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置任务为运行状态
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
public void SetTaskRunning(Guid taskId)
|
||
{
|
||
if (_tasks.TryGetValue(taskId, out var task))
|
||
{
|
||
task.Status = TaskStatus.Running;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 完成任务
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <param name="result">任务结果</param>
|
||
public void CompleteTask(Guid taskId, object result)
|
||
{
|
||
if (_tasks.TryGetValue(taskId, out var task))
|
||
{
|
||
task.Status = TaskStatus.Completed;
|
||
task.Result = result;
|
||
task.CompletedAt = DateTime.UtcNow;
|
||
NotifyTaskResultInBackground(task);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 任务失败
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <param name="errorMessage">错误消息</param>
|
||
public void FailTask(Guid taskId, string errorMessage)
|
||
{
|
||
if (_tasks.TryGetValue(taskId, out var task))
|
||
{
|
||
task.Status = TaskStatus.Failed;
|
||
task.ErrorMessage = errorMessage;
|
||
task.CompletedAt = DateTime.UtcNow;
|
||
NotifyTaskResultInBackground(task);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 后台触发任务结果回调,避免阻塞调用线程
|
||
/// </summary>
|
||
/// <param name="task">任务状态</param>
|
||
private static void NotifyTaskResultInBackground(TaskStatusResponse task)
|
||
{
|
||
System.Threading.Tasks.Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
TaskCallbackService.NotifyTaskResult(task);
|
||
}
|
||
catch
|
||
{
|
||
// 回调失败不影响主流程
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消任务
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
public void CancelTask(Guid taskId)
|
||
{
|
||
if (_tasks.TryGetValue(taskId, out var task))
|
||
{
|
||
task.Status = TaskStatus.Cancelled;
|
||
task.CompletedAt = DateTime.UtcNow;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取任务状态
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <returns>任务状态响应</returns>
|
||
public TaskStatusResponse GetTaskStatus(Guid taskId)
|
||
{
|
||
_tasks.TryGetValue(taskId, out var task);
|
||
return task;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查任务是否存在
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <returns>是否存在</returns>
|
||
public bool TaskExists(Guid taskId)
|
||
{
|
||
return _tasks.ContainsKey(taskId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取任务结果(仅用于向后兼容)
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <returns>任务结果</returns>
|
||
public object GetTaskResult(Guid taskId)
|
||
{
|
||
if (_tasks.TryGetValue(taskId, out var task) && task.Status == TaskStatus.Completed)
|
||
{
|
||
return task.Result;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 存储统计结果(用于向后兼容现有代码)
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <param name="count">统计数量</param>
|
||
public void StoreStatsResult(Guid taskId, int count)
|
||
{
|
||
CompleteTask(taskId, count);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取统计结果(用于向后兼容现有代码)
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <returns>统计数量,如果不存在返回null</returns>
|
||
public int? GetStatsResult(Guid taskId)
|
||
{
|
||
if (_tasks.TryGetValue(taskId, out var task) &&
|
||
task.Status == TaskStatus.Completed &&
|
||
task.Result is int count)
|
||
{
|
||
return count;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清理过期任务(创建超过24小时的已完成任务)
|
||
/// </summary>
|
||
public void CleanupExpiredTasks()
|
||
{
|
||
var expiredTime = DateTime.UtcNow.AddHours(-24);
|
||
var expiredTasks = new List<Guid>();
|
||
|
||
foreach (var kvp in _tasks)
|
||
{
|
||
var task = kvp.Value;
|
||
if ((task.Status == TaskStatus.Completed ||
|
||
task.Status == TaskStatus.Failed ||
|
||
task.Status == TaskStatus.Cancelled) &&
|
||
task.CreatedAt < expiredTime)
|
||
{
|
||
expiredTasks.Add(kvp.Key);
|
||
}
|
||
}
|
||
|
||
foreach (var taskId in expiredTasks)
|
||
{
|
||
_tasks.TryRemove(taskId, out _);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取任务总数
|
||
/// </summary>
|
||
/// <returns>任务总数</returns>
|
||
public int GetTaskCount()
|
||
{
|
||
return _tasks.Count;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定状态的任务数量
|
||
/// </summary>
|
||
/// <param name="status">任务状态</param>
|
||
/// <returns>任务数量</returns>
|
||
public int GetTaskCountByStatus(TaskStatus status)
|
||
{
|
||
return _tasks.Values.Count(t => t.Status == status);
|
||
}
|
||
}
|
||
}
|