.Net Core中的长期运行任务

时间:2019-09-21 14:51:51

标签: c# asp.net-core

我目前正在使用.Net Core开发WebApi,我的Api方法之一将呼叫另一个Api(第三方)的号码,并且需要一些时间来返回响应,但是我不希望我们的Api使用者等待响应,而我想返回早期响应,即操作已开始。然后,我将为我们的消费者提供一个端点,通过它们可以了解该操作的状态。例如,我们的消费者调用api来生成100k记录,我的Api会针对该记录调用约20个并行调用第三方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中解决此类问题。

1 个答案:

答案 0 :(得分:0)

在控制器内部等待长时间运行的过程不是一个好习惯。 在我的项目中,我的处理方式是

  1. 长时间放置必要的数据(类似于批处理的ID) API中将运行过程运行到Azure队列
  2. 从特定队列中触发功能应用,因此API的职责是 将数据放入队列
  3. 从那里开始功能应用程序 完成流程的责任。
  4. 可能正在使用类似 signalR,您可以在流程完成时通知前端