mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-06 17:58:05 +02:00
86 lines
2.7 KiB
C#
86 lines
2.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Robust.Shared.Asynchronous
|
|
{
|
|
|
|
/// <summary>
|
|
/// An implementation of TaskScheduler that uses the ThreadPool scheduler
|
|
/// </summary>
|
|
public sealed class RobustTaskScheduler : TaskScheduler
|
|
{
|
|
|
|
public static readonly RobustTaskScheduler Instance = new RobustTaskScheduler();
|
|
|
|
private RobustTaskScheduler()
|
|
{
|
|
// private
|
|
}
|
|
|
|
public static void Execute(object? o)
|
|
{
|
|
switch (o)
|
|
{
|
|
case IThreadPoolWorkItem w:
|
|
w.Execute();
|
|
break;
|
|
case ValueTask v:
|
|
Instance.TryExecuteTask(v.AsTask());
|
|
break;
|
|
case Task t:
|
|
Instance.TryExecuteTask(t);
|
|
break;
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Schedules a task to the ThreadPool.
|
|
/// </summary>
|
|
/// <param name="task">The task to schedule.</param>
|
|
protected override void QueueTask(Task task)
|
|
{
|
|
if (task.IsCompleted) return;
|
|
|
|
var options = task.CreationOptions;
|
|
if ((options & TaskCreationOptions.LongRunning) == 0)
|
|
{
|
|
ThreadPool.UnsafeQueueUserWorkItem((IThreadPoolWorkItem) task, false);
|
|
}
|
|
else
|
|
{
|
|
var wantsToBeFair = (task.CreationOptions & TaskCreationOptions.PreferFairness) != 0;
|
|
new Thread(Execute)
|
|
{
|
|
Priority = wantsToBeFair ? ThreadPriority.BelowNormal : ThreadPriority.AboveNormal,
|
|
IsBackground = true
|
|
}.Start(task);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This internal function will do this:
|
|
/// (1) If the task had previously been queued, attempt to pop it and return false if that fails.
|
|
/// (2) Return whether the task is executed
|
|
///
|
|
/// IMPORTANT NOTE: TryExecuteTaskInline will NOT throw task exceptions itself. Any wait code path using this function needs
|
|
/// to account for exceptions that need to be propagated, and throw themselves accordingly.
|
|
/// </summary>
|
|
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
|
|
{
|
|
return task.IsCompleted;
|
|
}
|
|
|
|
protected override bool TryDequeue(Task task) => false;
|
|
|
|
protected override IEnumerable<Task> GetScheduledTasks() => Enumerable.Empty<Task>();
|
|
|
|
}
|
|
|
|
}
|