【问题标题】:Long Running Task in .Net Core.Net Core 中的长时间运行任务
【发布时间】:2020-01-22 06:45:33
【问题描述】:

我目前正在使用 .Net Core 开发 WebApi,我的一个 Api 方法将调用另一个 Api(第 3 方)的号码,返回响应需要一些时间,但我不希望我们的 Api 消费者等待响应,而不是我想返回早期响应,即操作开始。我将为我们的消费者提供一个端点,通过它他们可以获得该操作的状态。例如,我们的消费者调用 api 来生成 10 万条记录,我的 Api 将为此调用大约 20 次并行调用 3rd 方 api。所以我不希望消费者对这 20 个 api 响应。 目前我有这个代码:

 public async Task<ActionResult> GenerateVouchers([FromBody][Required]CreateVoucherRequestModel request, string clientId)
    {
        _logger.LogInformation(Request.Method, Request.Path);
        // await _voucherService.ValidateIdempotedKeyWithStatus(clientId, _idempotentHeader);
        //TODO: Check Voucher type & Status before Generating Voucher
        var watch = Stopwatch.StartNew();
        var vouchers = new List<VoucherCreateResponseModel>();
        var batchSize = 5000;
        int numberOfBatches = (int)Math.Ceiling((double)request.quantity / batchSize);
        int totalVoucherQuantity = request.quantity;
        request.quantity = 5000;
        var tasks = new List<Task<VoucherCreateResponseModel>>();
        for (int i = 0; i < numberOfBatches; i++)
        {
            tasks.Add(_client.GenerateVoucher($"CouponsCreate", request));
            vouchers.AddRange(await Task.WhenAll(tasks).ConfigureAwait(false));
        }

        // await _voucherService.GenerateVouchers(request, clientId, _idempotentHeader);
        watch.Stop();
        var totalMS = watch.ElapsedMilliseconds;

        return Ok();
    }

但即使我有ConfigureAwait(false),上面代码的问题也会等待所有 20 个请求执行,当所有请求的响应都返回时,api 使用者将得到响应,但是这 20 个请求中的每一个都会占用执行时间为 5 秒,因此我们的消费者在等待响应时可能会收到请求超时。

如何在 .Net Core 中解决此类问题。

【问题讨论】:

  • 使用 f.i. Hangfire 处理那种长时间运行的后台进程
  • 您一次只能有效地等待一项任务,因为 WhenAll 调用在您的 for 循环中。您添加到列表中,然后等待它完成,然后重复。您可能希望将 Tasks.WhenAll 移动到 after 循环。这并不能真正解决您的问题,但肯定是发布的代码有问题
  • 所以上面的API没有问题。 API 的消费者存在超时问题,因为 API 是长时间运行的,而消费者没有配置来处理长时间的延迟。你能给我们看看消费者的代码吗?
  • @TheodorZoulias 实际上我无权访问消费者代码,我们只是向他们提供端点的 URL,我们必须以这样的方式开发解决方案 1:让他们调用我们的 api要生成的记录数,2:我们的 api 将调用第三部分端点的数量,3:将向消费者返回操作已启动的响应,4:将提供将显示其先前 api 调用状态的端点。
  • 消费者是什么技术? Javascript?其他 C# 应用程序?

标签: c# asp.net-core


【解决方案1】:

在控制器内等待长时间运行的进程不是一个好习惯。 我的意见是,

  1. 长时间放置必要的数据(例如批次的 ID) 将进程运行到 API 中的 Azure 队列
  2. 从特定队列触发函数应用,所以API的职责是 将数据放入队列
  3. 从那里开始它的功能应用程序 完成流程的责任。
  4. 可能正在使用类似的东西 signalR 你可以在进程完成时通知前端

【讨论】:

    猜你喜欢
    • 2020-11-20
    • 2018-05-06
    • 2017-12-14
    • 2011-01-19
    • 2019-06-16
    • 1970-01-01
    • 2013-07-08
    • 2014-09-10
    • 1970-01-01
    相关资源
    最近更新 更多