任务调度器
任务调度器 ITaskScheduler
接口提供了运行作业的方法。
1、获得实例
要使用任务调度器,首先得获取到它的实例。我们不推荐使用 new 构造一个实例,而是使用 TaskSchedulerFactory
工厂类来创建一个实例。该工厂类提供一个 CreateScheduler 方法,可以接收一个 configName 参数,这个参数对应任务调度器配置(可参考 配置与扩展)中配置项的名称,如果未配置任务调度器配置项,则返回默认的任务调度器单例。如下所示:
[TestMethod]
public void TestCreateScheduler()
{
var scheduler = TaskSchedulerFactory.CreateScheduler();
Assert.IsNotNull(scheduler); // DefaultTaskScheduler
}
在使用 IOC
的环境中,也可以通过构造注入或属性注入得到 ITaskScheduler
的实例。如下所示:
public class HomeController : Controller
{
private readonly ITaskScheduler _scheduler;
public HomeController(ITaskScheduler scheduler)
{
_scheduler = scheduler;
}
}
2、使用方法
ITaskScheduler
接口有以下两个方法:
- StartExecutor 方法启动一个同步的任务执行器。
- StartExecutorAsync 方法启动一个异步的任务执行器。
这两个方法都是泛型方法,泛型参数只要实现 ITaskExecutor
或 IAsyncTaskExecutor
接口即可。如下所示:
[TestMethod]
public class StartExecutor()
{
var scheduler = TaskSchedulerFactory.CreateScheduler();
var option1 = new StartOptions<SampleExecutor>(TimeSpan.Zero, TimeSpan.FromSeconds(30));
scheduler.StartExecutor<SampleExecutor>(option1);
var option2 = new StartOptions<AsyncSampleExecutor>(TimeSpan.Zero, TimeSpan.FromSeconds(30));
option2.Arguments.Add("name", "fireasy"); //添加参数
scheduler.StartExecutorAsync<AsyncSampleExecutor>(option2);
}
public class SampleExecutor : ITaskExecutor
{
public void Execute(TaskExecuteContext context)
{
Console.WriteLine(DateTime.Now);
}
}
public class AsyncSampleExecutor : IAsyncTaskExecutor
{
public async Task ExecuteAsync(TaskExecuteContext context)
{
Console.WriteLine(DateTime.Now);
Console.WriteLine(context.Arguments["name"]);
}
}
StartOptions<T>
参数除了使用 Arguments 属性传递参数外,还可以使用 Initializer 属性,它是一个委托,用于执行器初始时对实例进行处理,比如设置属性等等。如下所示:
[TestMethod]
public class StartExecutor()
{
var scheduler = TaskSchedulerFactory.CreateScheduler();
var option = new StartOptions<SampleExecutor>(TimeSpan.Zero, TimeSpan.FromSeconds(30));
option.Initializer = s => s.Name = "fireasy";
scheduler.StartExecutor<SampleExecutor>(option);
}
public class SampleExecutor : ITaskExecutor
{
public string Name { get; set; }
public void Execute(TaskExecuteContext context)
{
Console.WriteLine(Name);
}
}
- Start 方法启动一个同步的委托。
- StartAsync 方法启动一个异步的委托。
这两个方法不需要实现 ITaskExecutor
或 IAsyncTaskExecutor
接口,只需要提供一个委托即可。如下所示:
[TestMethod]
public class StartExecutor()
{
var scheduler = TaskSchedulerFactory.CreateScheduler();
scheduler.Start(new StartOptions(TimeSpan.FromSeconds(5), TimeSpan.Zero), sp =>
{
Console.WriteLine(DateTime.Now);
});
scheduler.StartAsync(new StartOptions(TimeSpan.FromSeconds(5), TimeSpan.Zero), (sp, cancel) =>
{
return Task.Run(() => { Console.WriteLine(DateTime.Now); });
});
}
执行器的构造函数支持 DI
注入,你可以使用 IOC
中的对象,或是直接使用 IServiceProvider
来获取对应的实例。另外,TaskExecuteContext
参数中也有 IServiceProvider
对象,你也可以在方法里注入对象。如下所示:
public class SampleExecutor : ITaskExecutor
{
private readonly ICacheManager _cacheManager;
public SampleExecutor(ICacheManager cacheManager)
{
_cacheManager = cacheManager;
}
public string Name { get; set; }
public void Execute(TaskExecuteContext context)
{
var cacheManager = context.ServiceProvider.GetService<ICacheManager>();
Assert.IsTrue(_cacheManager == cacheManager);
}
}
3、任务运行器
ITaskRunner
接口用来运行任务,它的 Start 方法一般用于启动一个定时器,而 Stop 方法则是停止定时器。默认的运行器是 DefaultTaskRunner
和 DefaultAsyncTaskRunner
类,你可以自己定义一个运行器。