REST API 端点中异步后台代码执行的类型

问题描述 投票:0回答:1

我正在 ASP.NET 中实现 REST API 端点,它应该执行以下操作:

  1. 异步启动长时间运行的算法
  2. 启动算法后立即返回 202 接受(无需等待)

这就是端点的样子:

app.MapPut(
    "/api/instance/{id}",
    (int id, InstanceDto instanceDto, IInstanceRunningService service) =>
    {
        // Start the execution asynchronously and return ASAP
        service.RunInstance(instanceDto);
        return TypedResults.Accepted($"/api/instance/{id}");
    })

这就是服务中的

RunInstance
方法的样子:

public async Task RunInstance(InstanceDto instanceDto)
{
    // Asynchronously call another API that we are starting the execution of the algorithm
    // We do not need to wait for the response, we just want to start the algorithm ASAP (again no await)
    _ = this.AnotherApiClient.PutAsync(instanceDto);

    // Compute the algorithm and await the result
    var result = await Algorithm.Run(instanceDto.Parameters);
    
    // Finally call the other API again to notify that the computation finished
    await this.AnotherApiClient.PutAsync(instanceDto);
}

我想要实现的操作顺序是:

  1. 返回 202 已接受
  2. 通知另一个 API 计算正在开始(我们不关心这个 API 调用如何结束,因为我们将在第 4 步中发送另一个 API。)
  3. 计算算法
  4. 通知另一个API计算已完成

我无法找出实现这一目标的最佳方法。有很多选择:

  • service.RunInstance(instanceDto);
  • service.RunInstance(instanceDto).Start();
  • Task.Run(() => service.RunInstance(instanceDto))
  • 使 RunInstance 成为异步委托并执行
    delegate.BeginInvoke()
  • 创建
    Thread
    或使用
    ThreadPool
  • 也许使用更多异步方法以不同的方式实现服务
c# .net asynchronous asp.net-web-api async-await
1个回答
2
投票

我无法找出实现这一目标的最佳方法。有很多选择:

我认为他们都不是“最好的”。此类任务的常见方法是使用某种后台处理。 “简单”的方法是仅将内置服务与托管服务一起使用,特别是查看排队后台任务选项(您可以实例化多个“处理器”来处理同一个队列 - 例如,请参阅这个答案)。

也不要将已解析的依赖项(即

IInstanceRunningService service
)传递给您的处理程序任务/队列,因为它们的生命周期由原始请求的生命周期控制,并且一次性服务将随之处理,手动创建范围并解析它所需的所有内容- 例如,请参阅文档的在后台任务中使用范围服务部分。

或者,您可以考虑使用更高级的调度程序,如 HangfireQuartz 和/或利用队列/服务总线的异步处理。

© www.soinside.com 2019 - 2024. All rights reserved.