You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C#中API里的Fire-and-Forget模式在HTTP调用时失效?

三个Minimal API行为差异的原因解析

接收端API代码

var app = builder.Build();
app.MapGet("/testing", () =>
{
    Console.WriteLine("Received");
});
app.Run();

这是一个普通的接收请求API,只要收到/testing路径的请求,就会打印"Received"日志。


未发起HTTP调用的调用端API代码

var app = builder.Build();
app.MapGet("/call", () =>
{
     using var client = new HttpClient();
     client.GetAsync("http://localhost:5215/testing");
});
app.Run();

为什么没发起调用却返回200?

  • GetAsync是异步方法,但这里没有加await,代码只会创建一个异步任务,不会等待它执行完成就继续往下走。
  • using var client声明的HttpClient,会在当前API处理方法执行完毕后立刻被释放。而这个处理方法是同步的,执行到client.GetAsync这行后马上就结束了,HttpClient提前被释放,导致刚创建的异步请求直接被终止,实际没发起有效的HTTP调用。
  • 因为API处理方法同步执行完毕,所以直接给客户端返回200状态码。

延迟5秒发起调用的调用端API代码

var app = builder.Build();
app.MapGet("/call", () =>
{
    Task.Run(async () =>
    {
        await Task.Delay(5000);
        using var client = new HttpClient();
        await client.GetAsync("http://localhost:5215/testing");
    });
});
app.Run();

为什么返回200后5秒会发起调用?

  • Task.Run把内部的异步委托放到了后台线程池执行,和当前API的处理线程完全分离。
  • 当前API处理方法执行完Task.Run这一行就直接结束了,所以立刻给客户端返回200状态码。
  • 后台的异步委托会独立运行:先等待5秒,然后创建HttpClient,这里用await等待GetAsync执行完成,所以HttpClient会在请求结束后才被释放,不会提前终止请求,因此5秒后能成功发起HTTP调用。

内容的提问来源于stack exchange,提问作者user33276346

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:42:16