gpt4 book ai didi

c# - 为什么我的异步 ASP.NET Web API Controller 阻塞了主线程?

转载 作者:太空狗 更新时间:2023-10-29 21:05:19 24 4
gpt4 key购买 nike

我有一个 ASP.NET Web API Controller ,我认为可以异步操作。 Controller 设计为第一个请求休眠 20 秒,但立即为任何后续请求提供服务。所以我预期的时间表是这样的:

  1. 提出请求 1。
  2. 提出请求 2。
  3. 提出请求 3。
  4. 请求 2 个返回。
  5. 请求 3 个返回。
  6. 等待约 20 秒。
  7. 请求 1 次返回。

相反,在请求 1 完成之前,没有 请求返回。

我可以确认(根据调试输出),入口线程和休眠线程 ID 不同。我故意使用 TaskCreationOptions.LongRunning 强制休眠到一个单独的线程,但应用程序仍然拒绝服务任何新请求,直到休眠结束。

我是否遗漏了有关异步 Web API Controller 实际工作原理的一些基本知识?


public class ValuesController : ApiController
{
private static bool _firstTime = true;

public async Task<string> Get()
{
Debug.WriteLine("Entry thread id: {0}. Sync: {1}",
Thread.CurrentThread.ManagedThreadId,
SynchronizationContext.Current);
await LongWaitAsync();
return "FOOBAR";
}

private Task LongWaitAsync()
{
return Task.Factory.StartNew(() =>
{
if (_firstTime)
{
_firstTime = false;
Debug.WriteLine("Sleepy thread id: {0}. Sync: {1}",
Thread.CurrentThread.ManagedThreadId,
SynchronizationContext.Current);
Thread.Sleep(20000);
Debug.WriteLine("Finished sleeping");
}
},
CancellationToken.None,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
}
}

最佳答案

这个其实和服务器无关,和客户端有关。在第一个请求得到响应之前,Chrome 和 Firefox 似乎都不想发送它们认为是“重复”的请求。任一浏览器的单独“私有(private)” session 将立即从第二个请求返回。 Internet Explorer 9 似乎没有表现出这种行为。

为了与客户端实现隔离,我将以下客户端放在一起。

class Program
{
static void Main(string[] args)
{
var t1 = Task.Run(() => FetchData(1));
var t2 = Task.Run(() => FetchData(2));
var t3 = Task.Run(() => FetchData(3));

var index = Task.WaitAny(t1, t2, t3);
Console.WriteLine("Task {0} finished first", index + 1);

Task.WaitAll(t1, t2, t3);
Console.WriteLine("All tasks have finished");

Console.WriteLine("Press any key");
Console.ReadKey(true);
}

static void FetchData(int clientNumber)
{
var client = new WebClient();
string data = client.DownloadString("http://localhost:61852/api/values");
Console.WriteLine("Client {0} got data: {1}", clientNumber, data);
}
}

它的输出是:

  1. 客户端 2 获得数据:“FOOBAR”(在启动后的几毫秒内)
  2. 客户端 3 得到数据:“FOOBAR”
  3. 任务 2 首先完成
  4. (在这里等很久)
  5. 客户端 1 得到数据:“FOOBAR”
  6. 所有任务都完成了

关于c# - 为什么我的异步 ASP.NET Web API Controller 阻塞了主线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14996529/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com