C#中使用Task.WhenAll批量拉取股票价格时是否会为每个ticker创建新线程?
问题背景
现有获取股票价格的代码实现如下:
var tickers = Ticker.text.splice(',',' '); var service = new StockService(); var tickerLoadingTasks = new List<Task<IEnumerable<StockePrice>>>(); foreach(var ticker in tickers) { var loadTask = service.GetStockPriceFor(ticker,cancellationTokenSource.Token) tickerLoadingTasks.Add(loadTask); } await Task.WhenAll(tickerLoadingTasks); // code for updating UI
补充说明:GetStockPriceFor 方法会返回对应每只股票的价格列表的Task对象,疑问是tickers中的每个值是否都会对应创建新线程。
核心解答
直接结论
不会为tickers中的每个值单独创建新线程
详细解释
- Task不是线程的等价物,它只是异步操作的状态标识。
GetStockPriceFor属于典型的IO密集型异步操作,底层一般是发起网络请求查询股票数据,这类操作依赖操作系统的IO完成端口实现,全程不需要占用独立线程等待IO返回。 - 代码中的foreach循环仅在当前线程上依次发起异步请求,把每个请求对应的Task存入列表,整个发起请求的过程不会创建新线程。
- 当某只股票的价格查询请求完成后,运行时才会从线程池中调度一个空闲线程执行后续的收尾逻辑,多个请求的回调会复用线程池的现有线程,不会为每个请求分配专属线程。
- 就算
GetStockPriceFor特殊实现为CPU密集型逻辑,内部用Task.Run委托给线程池执行,也只是复用线程池的已有线程,不会每次调用都创建全新的系统线程。
额外说明
你当前用Task.WhenAll批量等待所有异步请求完成的写法,是IO密集型高并发场景的标准最佳实践,相比为每个请求创建独立线程同步阻塞等待的方案,能节省大量线程开销,支持更高的并发量。
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

