在.NET开发中,C#任务调度器(TaskScheduler)是控制任务如何以及在何处执行的核心组件。默认情况下,.NET使用线程池调度器来运行任务,但在某些高级场景中,我们可能需要自定义调度逻辑——比如将任务限制在特定线程、按优先级执行,或用于UI线程同步等。本教程将手把手教你如何创建一个自定义TaskScheduler,即使你是编程小白也能轻松上手!

在C#中,Task 是异步编程的基本单元。而 TaskScheduler 负责决定这些任务何时、在哪个线程上执行。.NET 提供了几个内置调度器:
TaskScheduler.Default:使用线程池(最常用)TaskScheduler.FromCurrentSynchronizationContext():用于UI线程(如WPF/WinForms)但有时我们需要更精细的控制,这就引出了.NET并发编程中的高级技巧——自定义调度器。
以下是一些典型应用场景:
下面我们将创建一个名为 SingleThreadTaskScheduler 的调度器,它会将所有任务放入一个专用后台线程中顺序执行。
using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;public class SingleThreadTaskScheduler : TaskScheduler, IDisposable{ // 任务队列(线程安全) private readonly BlockingCollection<Task> _taskQueue = new(); // 专用工作线程 private readonly Thread _workerThread; // 标记是否已释放 private bool _disposed = false; public SingleThreadTaskScheduler() { // 启动专用线程 _workerThread = new Thread(RunOnCurrentThread) { IsBackground = true }; _workerThread.Start(); } // 调度器核心:将任务加入队列 protected override void QueueTask(Task task) { if (_disposed) throw new ObjectDisposedException(GetType().Name); _taskQueue.Add(task); } // 尝试在当前线程执行任务(用于内联执行优化) protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { // 只有在我们的工作线程中才允许内联执行 if (!_disposed && Thread.CurrentThread == _workerThread) { TryExecuteTask(task); return true; } return false; } // 返回调度器关联的所有任务(用于调试等) protected override IEnumerable<Task> GetScheduledTasks() { if (_disposed) throw new ObjectDisposedException(GetType().Name); return _taskQueue.ToArray(); } // 工作线程主循环 private void RunOnCurrentThread() { foreach (var task in _taskQueue.GetConsumingEnumerable()) { TryExecuteTask(task); } } // 清理资源 public void Dispose() { if (!_disposed) { _disposed = true; _taskQueue.CompleteAdding(); _workerThread?.Join(TimeSpan.FromSeconds(5)); _taskQueue.Dispose(); } }}使用非常简单!只需在创建 Task 时指定你的调度器即可:
using var scheduler = new SingleThreadTaskScheduler();// 使用自定义调度器启动任务var task1 = Task.Factory.StartNew(() => { Console.WriteLine($"任务1在线程 {Thread.CurrentThread.ManagedThreadId} 执行");}, CancellationToken.None, TaskCreationOptions.None, scheduler);var task2 = Task.Factory.StartNew(() => { Console.WriteLine($"任务2在线程 {Thread.CurrentThread.ManagedThreadId} 执行");}, CancellationToken.None, TaskCreationOptions.None, scheduler);Task.WaitAll(task1, task2);// 输出结果将显示两个任务在同一个线程ID上执行!QueueTask、TryExecuteTaskInline 和 GetScheduledTasks 三个方法。QueueTask 中执行耗时操作,否则会阻塞任务提交。IDisposable 以优雅关闭线程和清理资源。SynchronizationContext 而非自定义调度器。通过本文,你已经掌握了如何在C#中实现一个基本的自定义TaskScheduler。这不仅是理解.NET并发编程底层机制的重要一步,也为构建高性能、高可控性的应用程序打下基础。记住,异步任务调度虽强大,但也需谨慎使用——确保你的调度逻辑不会成为性能瓶颈。
希望这篇教程能帮助你在C#任务调度器的学习之路上迈出坚实的一步!如有疑问,欢迎在评论区交流。
本文由主机测评网于2025-12-26发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20251212885.html