using System;
using System.Collections.Concurrent;
namespace XGame.Framework.ThreadScheduler
{
///
/// 线程调度
///
public static class ThreadSchedulers
{
private class TaskInfo
{
public Action Action;
public object Context;
public void Clear()
{
Action = null;
Context = null;
}
}
private static ConcurrentQueue _queueTasks = new ConcurrentQueue();
private static ConcurrentQueue _taskPool = new ConcurrentQueue();
public static void RunOnMainThread(Action action, object context)
{
var task = Get();
task.Action = action;
task.Context = context;
_queueTasks.Enqueue(task);
}
private static void Recycle(TaskInfo task)
{
if (task != null)
{
task.Clear();
_taskPool.Enqueue(task);
}
}
private static TaskInfo Get()
{
if (!_taskPool.TryDequeue(out TaskInfo task))
task = new TaskInfo();
return task;
}
public static void Update()
{
while (_queueTasks.TryDequeue(out TaskInfo task))
{
if (task != default)
{
try
{
task.Action.Invoke(task.Context);
}
catch (Exception e)
{
if (e.InnerException != null)
{
Log.Error($"[ThreadSchedulers] Message: {e.InnerException.Message},\n" +
$"StackTrace: {e.InnerException.StackTrace}");
}
else
{
Log.Error($"[ThreadSchedulers] Message: {e.Message} \n" +
$"StackTrace: {e.StackTrace}");
}
}
finally
{
Recycle(task);
}
}
}
}
public static void Dispose()
{
while (_queueTasks.TryDequeue(out var task)) ;
while (_taskPool.TryDequeue(out var task)) ;
}
}
}