OvertakingLegend/Assets/Script/Tool/TaskSchedulerManager.cs

142 lines
3.6 KiB
C#
Raw Normal View History

2025-03-24 03:08:22 +00:00
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
/// <summary>
/// <20><><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ
/// </summary>
public class TaskSchedulerManager : MBSingletonManager<TaskSchedulerManager>
{
/// <summary>
/// <20><><EFBFBD>񷵻<EFBFBD><F1B7B5BB><EFBFBD><EFBFBD>̵߳Ķ<CCB5><C4B6><EFBFBD>
/// </summary>
private ConcurrentQueue<Action> mainThreadQueue = new ConcurrentQueue<Action>();
/// <summary>
/// <20><><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
private Dictionary<int, Task> tasks = new Dictionary<int, Task>();
/// <summary>
/// <20><><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CancellationTokenSource
/// </summary>
private Dictionary<int, CancellationTokenSource> taskCancellationTokens = new Dictionary<int, CancellationTokenSource>();
/// <summary>
/// <20><><EFBFBD><EFBFBD>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
private int taskIdCounter = 0;
private void Update()
{
// <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (mainThreadQueue.TryDequeue(out var task))
{
task.Invoke();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD><EFBFBD>
List<int> completedTaskIds = new List<int>();
foreach (var taskEntry in tasks)
{
if (taskEntry.Value.IsCompleted)
{
completedTaskIds.Add(taskEntry.Key);
}
}
foreach (var taskId in completedTaskIds)
{
tasks.Remove(taskId);
taskCancellationTokens.Remove(taskId);
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="taskFunc"><3E><EFBFBD><ECB2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="onCompleted"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA>Ļص<C4BB></param>
/// <returns><3E><><EFBFBD><EFBFBD>ID</returns>
public int RunTask(Func<CancellationToken,Task> taskFunc, Action onCompleted = null)
{
int taskId = taskIdCounter++;
var cts = new CancellationTokenSource();
taskCancellationTokens[taskId] = cts;
var task = Task.Run(async () =>
{
try
{
await taskFunc(cts.Token);
if (onCompleted != null)
{
mainThreadQueue.Enqueue(onCompleted);
}
}
catch (OperationCanceledException)
{
Debug.Log($"<22><><EFBFBD><EFBFBD> {taskId} <20>ѱ<EFBFBD>ȡ<EFBFBD><C8A1>");
}
catch (Exception ex)
{
Debug.LogError($"<22><><EFBFBD><EFBFBD> {taskId} ִ<><D6B4>ʧ<EFBFBD><CAA7>: {ex.Message}");
}
}, cts.Token);
tasks[taskId] = task;
return taskId;
}
/// <summary>
/// ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="taskId"><3E><><EFBFBD><EFBFBD>ID</param>
public void CancelTask(int taskId)
{
if (taskCancellationTokens.TryGetValue(taskId, out var cts))
{
cts.Cancel();
Debug.Log($"<22><><EFBFBD><EFBFBD> {taskId} <20><>ȡ<EFBFBD><C8A1>");
}
else
{
Debug.LogWarning($"δ<>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD> {taskId}");
}
}
/// <summary>
/// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public void WaitForAllTasks()
{
Task.WhenAll(tasks.Values).Wait();
}
/// <summary>
/// ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public void CancelAllTasks()
{
foreach (var cts in taskCancellationTokens.Values)
{
cts.Cancel();
}
Debug.Log("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>");
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public void ClearAllTasks()
{
CancelAllTasks();
tasks.Clear();
taskCancellationTokens.Clear();
mainThreadQueue.Clear();
}
}