142 lines
3.6 KiB
C#
142 lines
3.6 KiB
C#
|
|
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();
|
|||
|
|
}
|
|||
|
|
}
|