Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Ninject、Parallel.ForEach和InThreadScope()_C#_Multithreading_Inversion Of Control_Ninject - Fatal编程技术网

C# Ninject、Parallel.ForEach和InThreadScope()

C# Ninject、Parallel.ForEach和InThreadScope(),c#,multithreading,inversion-of-control,ninject,C#,Multithreading,Inversion Of Control,Ninject,我希望就如何与Ninject一起实施以下内容提出建议: 我有一个多线程应用程序。它同时运行大约20个非常独立的线程。在应用程序启动时,我使用InThreadScope()通过Ninject将一个接口绑定到一个对象,所有这些都可以正常工作。每个线程接收特定于其线程的对象(每个对象的构造函数实例化许多特定于线程的标志) 每个线程所做的大部分工作都是等待数据存储完成这个过程。因此,为了进一步优化线程,我们在主20个线程中实现了Parallel.ForEach逻辑。我希望Paralell.ForEach

我希望就如何与Ninject一起实施以下内容提出建议:

我有一个多线程应用程序。它同时运行大约20个非常独立的线程。在应用程序启动时,我使用InThreadScope()通过Ninject将一个接口绑定到一个对象,所有这些都可以正常工作。每个线程接收特定于其线程的对象(每个对象的构造函数实例化许多特定于线程的标志)

每个线程所做的大部分工作都是等待数据存储完成这个过程。因此,为了进一步优化线程,我们在主20个线程中实现了Parallel.ForEach逻辑。我希望Paralell.ForEach生成的线程能够获得与其父线程相同的绑定。但是,我不能简单地将接口重新绑定到Parallel.ForEach中的适当对象,我只是不知道绑定的对象是什么-在parallell.ForEach中,我只能使用接口

在Paralell.ForEach启动之前,在运行时从内核中检索绑定并在循环中重新绑定它们的正确方法是什么

编辑:试图包括详细的逻辑/伪代码:

每个线程一旦启动就会执行如下操作:

Kernel.Bind<ILoggingContext>().To<Application1LoggingContext>().InThreadScope();
Kernel.Bind().To().InThreadScope();
但是,当Parallel.ForEach()从各个线程内部启动时,我不再能够访问Application1LoggingContext对象,并且无法将ILoggingContext重新绑定到它。这是因为Parallel.ForEach()是从基类运行的,它不知道需要绑定到哪个应用程序日志上下文。这是在每个应用程序内部完成的,在启动大20个线程时完成

我想修改基类,即启动Parallel.ForEach()的基类,并确保在Parallel.ForEach线程新创建的每个线程中,ILOGingContext仍然绑定到Application1LoggingContext(一般),以便我可以执行以下操作:

var ctx = Kernel.Get<ILoggingContext>();
var ctx=Kernel.Get();

能否在闭包中捕获ILogingContext以传递给Parallel.ForEach()迭代

启动Parallel.ForEach()的基类方法(
StartUpBase.Start()
)可以从父线程上的上下文感知派生类型(
startupplication1
)调用。派生类型可以从Ninject内核获取
ilogingcontext
,您希望将其传递给子类并传递给基类方法,然后基类方法通过闭包将其传递给并行迭代:例如:

abstract class StartUpBase
{
    public abstract void Start();

    protected void StartApplication<T>(ILoggingContext ctx, IEnumerable<T> enumerableWork)
    {
        Parallel.ForEach(enumerableWork, iter =>
            {
                // this code can refer to ctx e.g.
                ctx.Log(message);
            });
    }
}

internal class StartupApplication1<T> : StartUpBase
{
    // setup of this is elsewhere...
    private IEnumerable<T> _enumerableWork;

    public override void Start()
    {
        ILoggingContext ctx = Kernel.Bind<ILoggingContext>()
            .To<Application1LoggingContext>().InThreadScope();
        StartApplication(ctx, _enumerableWork);
    }
}
抽象类StartUpBase
{
公共摘要void Start();
受保护的void StartApplication(ILoggingContext ctx,IEnumerable enumerableWork)
{
Parallel.ForEach(enumerableWork,iter=>
{
//此代码可参考ctx,例如。
ctx.Log(消息);
});
}
}
内部类StartupApplication1:StartUpBase
{
//这个的设置在别处。。。
私有IEnumerable enumerableWork;
公共覆盖无效开始()
{
ILoggingContext ctx=Kernel.Bind()
.To().InThreadScope();
StartApplication(ctx,_enumerableWork);
}
}

看来我已经解决了这个问题。下面是在Parallel.Foreach内重新绑定绑定的一般方法。根据绑定的复杂性/数量,这可能适用于您,也可能不适用于您

var logBinding = Kernel.GetBindings(typeof(ILoggingContext)).FirstOrDefault();

Parallel.ForEach(items, n =>
                            {
                                if (Kernel.GetBindings(typeof(ILoggingContext)).Count() == 0 && logBinding != null)
                                    Kernel.AddBinding(logBinding);

                                //do stuff
                                }
                            });

你可以发布你想如何使用Paralell.ForEach的示例代码(伪代码)吗?谢谢你的回复。不幸的是,Parallel.ForEach中的代码正在执行Kernel.Get(),它必须继续执行soWell,然后在逻辑上,如果您坚持使用内核从迭代中获取ILOGingContext,则必须使用InThreadScope以外的其他工具,如自定义提供程序。听起来你让你的生活变得很复杂!发布更多的代码可能会帮助您获得更好的答案。代码非常复杂。我希望能够以某种方式迭代内核中的Bindings集合,以通用方式重新绑定ILogingContext。理想情况下,应该只有您的“组合根”(ref:Mark Seemann)知道您的IoC容器。。。在这种情况下,“父线程”似乎扮演了复合根的角色——也许您可以回顾一下您的子线程是否需要知道Ninject内核?