在Parallel.Foreach循环(线程)中创建组件时,请保持成分根

时间:2019-04-15 15:36:50

标签: multithreading autofac

我正在尝试学习Parallel ForEach循环内的正确方法,以不引用合成根目录,而是根据合成根目录中引用的组件创建线程组件。

这是合成的根代码:

var builder = new ContainerBuilder();
builder.RegisterType<OperationFiscalCalendarSql>().As<IOperationCloser>().InstancePerDependency();
builder.RegisterType<SQLMessagePoller>().As<IMessagePoller>().SingleInstance();
...
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
...
}

这是在具有foreach循环的poller对象中引用的代码:

Parallel.ForEach(messageHeaders, new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism }, messageHeader => {
    ...
    var sapCloser = new OperationFiscalCalendarSql(closeObj, repostiory);
    ...                        
}); 

请注意,我想要一个IOperationCloser实例,而不是对“新的” OperationFiscalCalendarSql对象进行硬编码。

我了解构造函数注入,只是不知道在任何循环中如何注入IOperationCloser。

1 个答案:

答案 0 :(得分:1)

You can inject a factory in your Poller object with Func<IOperationCloser> and then get a new instance in the ForEach loop.

In your case it may be even better to create your own ILifetimeScope. You can do this by injecting ILieetimeScope in Poller and then call BeginLifetimeScope and Resolve in the loop.

Parallel.ForEach(messageHeaders, ..., m => {
    using(ILifetimeScope childScope = scope.BeginLifetimeScope()){
        var param1 = new TypedParameter(m);
        var closer = childScope.Resolve<IOperationCloser>(param1);
    });
});