如何使用Entity Framework调试异步/等待(多线程)问题?

时间:2017-09-14 22:19:58

标签: c# .net multithreading entity-framework asynchronous

我已经“继承”了使用AutoMapper和EntityFramework的多层ASP.NET核心项目。 它也大量使用async / await。

只要有多个同时发出的请求,我就会从EntityFramework收到一个InvalidOperationException,通知我“在上一次异步操作完成之前,第二次操作已在此上下文中启动。”

我已经玩过生命周期设置(一切都设置为Scoped)并且想到将一切设置为Transient已经解决了这个问题作为临时解决方法。但是在略微清理我的代码之后,我可以将它合并到主分支中,问题又回来了。

无论如何,我认为创建一个示例项目来复制问题会更好。但这也不起作用。我试图复制确切的项目结构,使用相同(过时)的Entity Framework等版本,但没有运气。一切都很好,都有“Scoped”和“Transient”的生命。

您将如何尝试调试此问题? 我已经添加了代码来记录内存中的地址,如下所示:

    private static string GetAddress(object a)
    {
        GCHandle handle = GCHandle.Alloc(a, GCHandleType.Weak);
        IntPtr pointer = GCHandle.ToIntPtr(handle);
        handle.Free();
        return "0x" + pointer.ToString("X");
    }

    public async Task<IActionResult> GetAll()
    {
        Debug.WriteLine("######## {0:00}: Controller {1}\tManager {2}\tRepository\t\t\tContext\t\t\t(DepartmentController.GetAll)", Thread.CurrentThread.ManagedThreadId, GetAddress(this), GetAddress(_departmentManager));
        Thread.Sleep(2000); // To make it easier to reproduce the issue
        var departments = await _departmentManager.GetAllItems();
        return new ObjectResult(GetJsonObject(departments));
    }

但这并没有多大帮助。将生命周期设置为“Transient”,所有实例在不同的线程上都有不同的地址,因此它看起来并不像线程正在访问彼此的DbContexts。 我怀疑在某个地方存在一个非常微妙的问题,比如缺少一个关键字,即在不同的线程上运行代码。 我似乎无法弄清楚它是什么...... 任何帮助将受到高度赞赏。

0 个答案:

没有答案