c# - 为什么我的线程卡在 Entity Framework SaveChangesAsync 中?

标签 c# .net multithreading entity-framework asp.net-web-api

我们遇到了 Entity Framework 的一个奇怪问题。我们正在尝试向数据库中添加一个新对象,并且是从几个不同的位置进行的。两者都使用通过 nuget 包加载的以下代码:

public async Task<Guid> AddRecurrenceHistoryAsync(RecurrenceHistory recurrenceHistory, Guid recurrenceId)
{
    _logger.DebugLogInformation("+");

    try
    {
        using (RecurringPaymentsContext context = new RecurringPaymentsContext())
        {
            var recur = context.RecurringPayments.Single(r => r.Id == recurrenceId);
            if (recur.RecurrenceHistories == null)
            {
                _logger.DebugLogInformation($"No existing histories found");
                recur.RecurrenceHistories = new List<RecurrenceHistory>();
            }
            recur.RecurrenceHistories.Add(recurrenceHistory);
            _logger.DebugLogInformation($"Saving Changes");
            var result = await context.SaveChangesAsync();
            _logger.DebugLogInformation($"Changes Saved result: {result}");
        }
    }
    catch (Exception e)
    {
        _logger.DebugLogError(e.ToString());
        throw;
    }

    _logger.DebugLogInformation(string.Format("- return: {0}", recurrenceHistory.Id));
    return recurrenceHistory.Id;
}

从我们的控制台应用程序中执行此操作完美无缺,但是我们也尝试从 WebApi 服务端点(下面给出的简化测试代码)执行此操作,当从那里调用它时,代码卡在 var 结果上= await context.SaveChangesAsync(); 行。

Web 服务测试端点:

[HttpGet]
[Route("test")]
public HttpResponseMessage Test()
{
    var paymentHistory = new RecurrenceHistory()
    {
        SystemId = Guid.NewGuid(),
        TotalAmount = -1
    };
    _logger.DebugLogInformation("Adding recurrence history");
    paymentHistory.Id = _recurrenceHistoryRepository.AddRecurrenceHistoryAsync(paymentHistory, Guid.Parse("3c412e1b-7a87-e711-910c-0050569b7221")).Result;

    return Request.CreateResponse(true);
}

此测试端点尝试使用我们知道的 Guid 添加对象,该对象现在已经在数据库中,仅用于测试目的,但在运行时,代码会进入上述 var result = await context.SaveChangesAsync() ; 行然后卡住了。没有更多的记录,调试器就停在那里,永远不会返回。没有抛出异常,但是新行确实被添加到数据库中。

tl;dr 总结:

控制台应用程序可以成功调用此存储库方法来添加对象并可以继续,但是 Web 服务可以成功地将对象添加到数据库,但代码永远不会从 context.SaveChangesAsync() 返回> 方法。

我们尝试过的事情:

将有问题的失败行更改为 await Task.Run(() => context.SaveChangesAsync());,尝试将工作进程添加到服务的应用程序池,以及一些其他不值一提。

最佳答案

不要调用 .Result,这是一个阻塞调用,更重要的是,它会导致死锁。请改用 await 并让您的 Controller 方法返回一个 Task。这真的是async/await的101。参见 this以获得深入的解释。

关于c# - 为什么我的线程卡在 Entity Framework SaveChangesAsync 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45845296/

相关文章:

c# - 在页面加载时将焦点设置在文本框上

c# - WCF AddServiceReference 导致自定义工具错误,不生成代理

多线程程序的C++定时器中断

python multiprocessing - 将子进程日志记录发送到在父进程中运行的 GUI

c# - 将 DataRow 值转换为浮点型

c# - 限制 C# 中的泛型类型

C# 测试字符串是否为整数?

multithreading - 超线程处理器内核可以完全同时执行两个线程吗?

c# - 如何使用 POSTin c# 发出 HTTP 请求并发送一些 xml 数据

c# - 无法加载文件或程序集 'Microsoft.AspNet.Identity.EntityFramework' 或其依赖项之一。无法验证强名称签名