【问题标题】:async method in asp.net causing requests to never finishasp.net 中的异步方法导致请求永远不会完成
【发布时间】:2014-09-07 19:28:27
【问题描述】:

我有一个看似工作正常的异步 asp.net mvc 4 操作。

通过它进行调试按预期工作。

问题是当它投入生产时,一段时间后请求开始堆积并且没有任何东西得到处理。这听起来像是某种僵局,但我不确定问题出在哪里。

public async Task<ActionResult> Index()
{
    //some work
    var user = PopulateUser();
    try
    {
        await DynamoUtil.WriteToDynamoAsync(user);
    }
    catch (Exception x)
    { 
        //standard log4net logging
        _log.Error("Error writing to dynamo", x);
    }

    //.. some more work

    return Redirect(url);
}

我的WriteToDynamoAsync 方法与此类似

public static class DynamoUtil
{
    //..

    //instantiated in static constructor
    private static DynamoDBContext _context;

    public static async Task WriteToDynamoAsync(User user)
    {
        try
        {
            var batch = _context.CreateBatchWrite<User>();
            batch.AddPutItem(user);
            await batch.ExecuteAsync().ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            _log.Error("Error executing batch", ex);
            throw;
        }
    }
}

要注意的另一件事是,如果我在 WriteToDynamoAsync 方法上删除第一个 await,它可以正常工作。一切都在继续前进。这样做的问题是我想真正确保项目被写入 Dynamo,如果没有,我希望记录异常。

任何人都可以看到上面的问题,或者有什么建议吗?

另外,我尝试过使用和不使用ConfigureAwait,这似乎不会改变任何结果。

我无法重现不受欢迎的行为调试,但是当它处于活动状态并受到每秒 4 到 5 个请求的影响时,整个网站将在一两分钟内停止工作。

【问题讨论】:

  • _context.CreateBatchWrite&lt;User&gt;(); 线程安全吗?如果你从多个线程调用同一个类到实体框架之类的东西中,你可能会导致死锁。
  • @ScottChamberlain The DynamoDBContext object is thread-safe 来自亚马逊文档aws.amazon.com/articles/2790257258340776,所以我认为它是。不过,我还没有窥探该方法的来源。
  • 很难调试。此代码是否同步,您可以暂停(远程)调试器并查看线程在做什么。尝试将其转换为同步代码以进行测试和远程调试。
  • 您还可以登录到您的 aws 控制台并确保您对 dynamodb 表的请求没有受到限制。

标签: c# asp.net-mvc async-await amazon-dynamodb


【解决方案1】:

首先,您已经在 WriteToDynamoAsync 本身记录了任何潜在的异常,那么为什么还要在 Index 中记录呢?

其次,您的问题很可能是您在生产中的并发请求比在开发中要多得多,并且在前一种情况下您的数据库连接要慢得多(在后一种情况下,它甚至可能在同一台机器上)。

第三,不要在Index 中使用ConfigureAwait(false),因为你需要它返回到完全相同的请求线程(它不是静态的)。

最后,您必须加快生产数据库连接,或者以某种方式降低其使用率(减少数据库调用)。

另外,如果它对业务至关重要,请不要从WriteToDynamoAsync 中删除await,否则如果应用程序域回收,它可能无法完成,您甚至都不知道。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多