C# Autofac - InstancePerLifetimeScope 和多线程:并发问题

C# Autofac - InstancePerLifetimeScope and multi thread: concurrency issues

我有一个使用 Autofac 的 WCF 服务 .net framework 4.0。

然后我有几个依赖是这样解决的:

builder.RegisterType<LogicA>().As<ILogicA>().InstancePerLifetimeScope();

我在 class 中有一个操作,其中通过参数注入依赖项,因为 class 本身也在与依赖项相同的 class 上被引用:

public void DoStuff(List<string> items, ILogicA logicA){
foreach (var item in items)
{
    System.Threading.ThreadPool.QueueUserWorkItem(queueUserWorkItem =>
    {
        logicA.DoOtherStuff(item);
    });
}}

发生的事情是在 DoOtherStuff 方法内部,它调用其他 classes,其中一些具有为集合中的每个项目填充的状态(属性),最后数据保存在数据库中.

最后,当项目集合开始有一些项目(超过 6 或 7)时,有时我开始收到主键违规错误(这使用引擎盖下的 SQL 服务器)并且如果我打开一个 SQL 分析器,我可以看到对同一 ID 的调用超过 1 个,而如果我将日志记录放在上面的 foreach 块的开头,我就看不到任何重复的东西,这让我认为也许这个 logicA 参数原来不是线程安全的。

我应该在我的 QueueUserWorkItem 块中解决这种对需求的依赖性,还是我在这里遗漏了其他任何东西?

感谢您的帮助

在不了解更多上下文的情况下很难说,但这似乎是一个经典的工作单元场景,您可能希望为每个后台操作分配生命周期范围。

public void DoStuff(List<string> items, ILifetimeScope scope){
foreach (var item in items)
{
        var newScope = scope.BeginLifetimeScope();
System.Threading.ThreadPool.QueueUserWorkItem(queueUserWorkItem =>
    {
                    using (newScope)
                    {
                          var logicA = newScope.Resolve<ILogicA>();
              logicA.DoOtherStuff(item);
                     }
    });
}}

即使这不完全正确,通常明智的做法是不要在任何工作单元之间共享一个生命周期范围;共享状态可能会有点奇怪。