用于AspnetCore的基于IHostedService的后台任务库,该包主要解决了在HTTP请求执行比较长时间的任务时在后台新建线程执行而HTTP马上返回时依赖注入的服务被销毁的问题。
解放双手不再需要做复杂的服务生命周期管理,不再需要自己新建Scope
搜索并引用包:
Mango.BackgroundTask
service.AddBackgroundTaskQueue();该包模仿MediatR的交互方式,首先创建任务请求对象实现IBackgroundTaskRequest接口:
public class MyTaskRequest : IBackgroundTaskRequest
{
//...
}然后创建任务处理类实现IBackgroundTaskHandler接口:
public class MyTaskHandler : IBackgroundTaskHandler<MyTaskRequest>
{
private readonly ISomeService _someService;
public MyTaskHandler(ISomeService someService)
{
//在处理程序中可以像其他普通的服务一样使用依赖注入
_someService = someService;
}
public Task Handler(MyTaskRequest request, CancellationToken token = default)
{
//编写处理程序
}
}然后在Startup.cs中注册MyTaskHandler:
service.AddScoped<MyTaskHandler>();在任意需要发布任务的地方利用依赖注入IBackgroundTaskProvider接口,像后台线程发布任务。
public class SendTaskService
{
private readonly IBackgroundTaskProvider _provider;
public SendTaskService(IBackgroundTaskProvider provider)
{
//依赖注入IBackgroundTaskProvider接口
_provider = provider;
}
public async Task SomeMethodAsync()
{
//todo...
//发布任务
await _provider.Send(new MyTaskRequest());
//todo...
}
}该包和MediatR有什么区别?直接用MediatR不能实现吗?
首先因为生命周期的原因在一个http请求结束后依赖注入的服务就有可能会被销毁,所以当需要执行时间长的任务而要求http能马上返回时,就会出现引用了被销毁对象而异常的情况。而像MediatR这种中介者模式的库并不会对这种超过生命周期的服务做任何处理,所以大概率任然会发生异常,除非自己手动处理。
该包只是在交互方式上模仿MediatR,本身并没有引用到MediatR。
也希望大家都可以来维护或者贡献这个小小又实用的包。