我在 owin 驱动的 web api 项目中使用 autofac。我已经到了需要“即发即忘”的一些数据处理的地方。这通常不是问题。但是由于依赖关系是由 autofac 中间件管理的每个请求的生命周期范围控制的。我不能在非等待的 async
方法中使用非托管资源(这是我需要做的)。
//for example...
public async Task<IEnumerable<MyThings>> GetThings(){
var things = await _thingRepo.GetInterestingThingsAsync();
//fire and forget. -- not awaiting
InjectedObject.DoThingsAsync(things);
return things;
}
这里的问题是我需要在 DoThingsAsync
中使用其他注入(inject)的资源(非托管资源)。目前这会中断,因为它们会在 Owin 请求结束时被处理掉。
我可以为每次调用创建一个子生命周期范围,但我希望它们可能是一种更简洁的方式来做这些事情。
更新:
随着 .Net Framework 4.5.2 的到来,我现在可以使用
HostingEnvironment.QueueBackgroundWorkItem
这是首选,因为它会阻止 IIS 在工作项完成之前进行回收。
我想我找到了适合我的用例的解决方案..
我只是在我需要的地方注入(inject)这个类:
public class AsyncTask : IAsyncTask
{
private ILifetimeScope _lifetimeScope;
public AsyncTask(ILifetimeScope lifeTimeScope)
{
//disposed of by owning scope...
_lifetimeScope = lifeTimeScope;
}
public async Task Fire<T>(Func<T,Task> asyncAction)
{
using (var scope = _lifetimeScope.BeginLifetimeScope())
{
await asyncAction(scope.Resolve<T>());
}
}
}
public interface IAsyncTask
{
Task Fire<T>(Func<T, Task> action);
}
然后..
_asyncTask.Fire<IEmailService>(svc => svc.SendMillionsOfEmailsAsync(content));
我是一名优秀的程序员,十分优秀!