77 lines
2.4 KiB
C#
77 lines
2.4 KiB
C#
using System;
|
|||
|
|
using System.Threading;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
|
||
|
|
namespace PCL.Core.Utils.Threading;
|
||
|
|
|
||
|
|
// Partly generated by o4-mini-high (20250709)
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 使用两个线程池的调度器,分为 CPU 线程池和 IO 线程池,分别负责 CPU 密集型任务和 IO 密集型任务
|
||
|
|
/// </summary>
|
||
|
|
public class DualThreadPool
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// 两线程池分别计算的最大线程数
|
||
|
|
/// </summary>
|
||
|
|
public int MaxThread { get; }
|
||
|
|
|
||
|
|
private readonly TaskFactory _ioFactory;
|
||
|
|
private readonly TaskFactory _cpuFactory;
|
||
|
|
private readonly CancellationTokenSource _cts = new();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 初始化 <see cref="DualThreadPool"/> 实例
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="maxThread">参考 <see cref="MaxThread"/>,最小为 1</param>
|
||
|
|
/// <exception cref="ArgumentOutOfRangeException">最大线程数小于 1</exception>
|
||
|
|
public DualThreadPool(int maxThread)
|
||
|
|
{
|
||
|
|
if (maxThread < 1) throw new ArgumentOutOfRangeException(nameof(maxThread));
|
||
|
|
|
||
|
|
MaxThread = maxThread;
|
||
|
|
|
||
|
|
var ioScheduler = new LimitedConcurrencyLevelTaskScheduler(maxThread);
|
||
|
|
var cpuScheduler = new LimitedConcurrencyLevelTaskScheduler(maxThread);
|
||
|
|
var cancellationToken = _cts.Token;
|
||
|
|
|
||
|
|
// DenyChildAttach 防止子任务跑到外层 scheduler
|
||
|
|
_ioFactory = new TaskFactory(
|
||
|
|
cancellationToken,
|
||
|
|
TaskCreationOptions.DenyChildAttach,
|
||
|
|
TaskContinuationOptions.None,
|
||
|
|
ioScheduler);
|
||
|
|
|
||
|
|
_cpuFactory = new TaskFactory(
|
||
|
|
cancellationToken,
|
||
|
|
TaskCreationOptions.DenyChildAttach,
|
||
|
|
TaskContinuationOptions.None,
|
||
|
|
cpuScheduler);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 提交一段 IO 密集工作
|
||
|
|
/// </summary>
|
||
|
|
public Task QueueIo(Action work) => _ioFactory.StartNew(work);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 提交一段异步 IO 密集工作
|
||
|
|
/// </summary>
|
||
|
|
public Task QueueIo(Func<Task> work) => _ioFactory.StartNew(work).Unwrap();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 提交一段 CPU 密集工作
|
||
|
|
/// </summary>
|
||
|
|
public Task QueueCpu(Action work) => _cpuFactory.StartNew(work);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 提交一段异步 CPU 密集工作
|
||
|
|
/// </summary>
|
||
|
|
public Task QueueCpu(Func<Task> work) => _cpuFactory.StartNew(work).Unwrap();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 取消所有正在执行的工作
|
||
|
|
/// </summary>
|
||
|
|
public void CancelAll() => _cts.Cancel();
|
||
|
|
}
|