Autofac无法处理后台任务

问题描述 投票:1回答:2

我有一个任务需要在后台的一个单独的线程中运行,我使用SignalR来报告进度。这工作不久前,我已经做了一些代码修改,但我现在完全失去了我收到的错误:

“从请求实例的作用域中看不到具有匹配'AutofacWebRequest'的标记的作用域。这通常表示SingleInstance()组件(或类似场景)正在请求按HTTP请求注册的组件。在Web集成下,总是从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖,而不是从容器本身请求。“

任何帮助是极大的赞赏!

    public ActionResult DoAction(IEnumerable<string> items){

    //...
    Func<CancellationToken, Task> taskFunc = CancellationToken => performAction(items);
    HostingEnvironment.QueueBackgroundWorkItem(taskFunc);
    //...
    }

    private async Task performAction(IEnumerable<string> items){
    var svc = AutofacDependencyResolver.Current.AppicationContainer.BeginLifetimeScope().Resolve<MyService>();
    svc.Method(items);
    }

public class MyService{
   private EntityContext db;

   public MyService(EntityContext db){

   this.db = db;
   }
}

在我的Startup.Container.cs文件中:

builder.RegisterType<MyService>().As<MyService>().InstancePerLifetimeScope();
   builder.RegisterType<EntityContext>().InstancePerRequest();
c# autofac
2个回答
5
投票

我最近使用这个answer和这个answer的帮助实现了类似的东西。您需要创建一个新的生命周期范围 - 这听起来像是在Web应用程序中执行此操作,因此您需要通过每个请求标记创建范围(下面的示例)。

另一个(非StackOverflow)answer提供类似的建议。

public Task Run<T>(Action<T> action)
{
    Task.Factory.StartNew(() =>
    {
        using (var lifetimeScope = _container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag))
        {
            var service = lifetimeScope.Resolve<T>();
            action(service);
        }
    });
    return Task.FromResult(0);
}

0
投票

基于以上代码的更新答案:

用法:

public class ServiceModule :Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {

        builder.RegisterType<AutoFac.AsyncRunner>().As<AutoFac.IAsyncRunner>().SingleInstance();
    }
}


public class Controller
{
private AutoFac.IAsyncRunner _asyncRunner;

public Controller(AutoFac.IAsyncRunner asyncRunner)
{

    _asyncRunner = asyncRunner;
}

public void Function()
{
    _asyncRunner.Run<IService>((cis) =>
   {
       try
       {
          //do stuff
       }
       catch
       {
           // catch stuff
           throw;
       }
   });
}
}

界面:

public interface IAsyncRunner
{
    Task Run<T>(Action<T> action);
}

班级:

public class AsyncRunner : IAsyncRunner
{
    private ILifetimeScope _lifetimeScope { get; set; }

    public AsyncRunner(ILifetimeScope lifetimeScope)
    {
        //Guard.NotNull(() => lifetimeScope, lifetimeScope);
        _lifetimeScope = lifetimeScope;
    }

    public Task Run<T>(Action<T> action)
    {
        Task.Factory.StartNew(() =>
        {
            using (var lifetimeScope = _lifetimeScope.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag))
            {
                var service = lifetimeScope.Resolve<T>();
                action(service);
            }
        });
        return Task.FromResult(0);
    }


}
© www.soinside.com 2019 - 2024. All rights reserved.