摘要
在C#中,TaskScheduler是一种非常有用的功能,它允许您在指定的时间或间隔内执行任务。TaskScheduler是一个抽象类,它提供了一个通用的方法来计划和执行任务。您可以使用TaskScheduler来调度多个任务,并且在多线程环境中控制它们的执行。
正文
写一个继承TaskScheduler的类
public class MyScheduler : TaskScheduler
{
protected override void QueueTask(Task task)
{
// 将任务排队到线程池中
ThreadPool.QueueUserWorkItem(_ => TryExecuteTask(task));
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
// 如果当前线程是调度器的线程,则在当前线程内执行任务
if (taskWasPreviouslyQueued && Thread.CurrentThread.IsThreadPoolThread)
return TryExecuteTask(task);
return false;
}
protected override IEnumerable<Task> GetScheduledTasks()
{
// 此方法用于调度器的内部追踪,不要求实现
return Enumerable.Empty<Task>();
}
}
在界面中定时调用
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void btnStart_Click(object sender, EventArgs e)
{
// 创建一个任务调度器
var taskScheduler = new MyScheduler();
// 计划执行任务
var startTime = DateTime.Now.AddSeconds(5); // 5秒后开始执行第一次任务
var interval = TimeSpan.FromSeconds(3); // 每隔3秒重复执行一次任务
ScheduleTask(taskScheduler, () => DoTask("计划任务"), startTime, interval);
}
private void ScheduleTask(TaskScheduler scheduler, Action action, DateTime startTime, TimeSpan interval)
{
Task.Factory.StartNew(async () =>
{
var delay = startTime - DateTime.Now;
if (delay.TotalMilliseconds > 0)
Thread.Sleep(delay);
while (true)
{
action();
// 等待指定的时间间隔
await Task.Delay(interval);
}
}, CancellationToken.None, TaskCreationOptions.LongRunning, scheduler);
}
private void DoTask(string taskName)
{
this.Invoke(() =>
{
txt.AppendText($"{taskName} executed at: {DateTime.Now}");
txt.AppendText(System.Environment.NewLine);
});
}
}
我们已经创建了一个自定义的任务调度器 MyScheduler,可以执行预定的任务。通过调用 ScheduleTask`方法,我们将任务添加到调度器中。在这个例子中,我们将在5秒后开始执行任务,并且每隔3秒重复执行一次。