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

为何这段C#代码输出4个星号而非预期的2个?

问题分析:为何C#代码输出4个星号而非预期的2个?

你的代码核心问题在于**IEnumerable<Task>的延迟执行特性**:

IEnumerable<Task> tasks = Enumerable.Range(0, 2)
    .Select(_ => Task.Run(() =>
    {
        Task.Delay(10);
        Console.Write("*");
    }));

IEnumerable<T>是延迟枚举的,这意味着每次你访问这个集合(比如调用Task.WhenAll(tasks)或者tasks.Count()),都会重新执行一遍Select里的逻辑:

  1. 执行await Task.WhenAll(tasks)时,会枚举tasks,创建2个新的Task.Run任务,每个任务输出一个*;
  2. 执行tasks.Count()时,会再次枚举tasks,又创建2个全新的Task.Run任务,这两个任务也会各自输出一个*;
  3. 第二次创建的任务没有被await,但它们的执行时机刚好会在控制台输出2 stars!前后触发,最终就出现了4个星号的情况。

修复方案

把IEnumerable<Task>转换成立即执行的集合类型(比如List<Task>),确保只创建一次任务:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        List<Task> tasks = Enumerable.Range(0, 2)
            .Select(_ => Task.Run(() =>
            {
                // 如果需要实际等待10ms,记得加上await
                // await Task.Delay(10);
                Console.Write("*");
            }))
            .ToList(); // 关键:立即执行Select,将结果存入List

        await Task.WhenAll(tasks);
        Console.Write($"{tasks.Count()} stars!");
    }
}

另外提一句:原代码里的Task.Delay(10)没有加await,这个延迟其实不会生效,任务会直接输出*,如果需要真的等待10毫秒再输出,记得加上await关键字。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:49:59