Task.Delay与Thread.Sleep的区别

5
private static async Task MainFunc()
{
    var watch = System.Diagnostics.Stopwatch.StartNew();

    List<Task<int>> list = new List<Task<int>>();

    for (int i = 1; i <= 3; i++)
    {
        list.Add(TaskFunc(i));
    }

    var taskResult = await Task.WhenAll(list);

    foreach (var item in taskResult)
    {
        Console.Write($"i= {item}.{ Environment.NewLine }");
    }

    list.Clear();

    watch.Stop();
    var elapsedMs1 = watch.ElapsedMilliseconds;

    Console.WriteLine($"Total execution time: { elapsedMs1 }");
    Console.WriteLine();


    watch.Restart();


    for (int i = 1; i <= 3; i++)
    {
        list.Add(Task.Run(() => ThreadFunc(i)));
    }

    var threadResult = await Task.WhenAll(list);

    foreach (var item in threadResult)
    {
        Console.Write($"i= {item}.{ Environment.NewLine }");
    }

    watch.Stop();
    var elapsedMs2 = watch.ElapsedMilliseconds;

    Console.WriteLine($"Total execution time: { elapsedMs2 }");
}

private static async Task<int> TaskFunc(int i)
{

    if (i == 1)
        await Task.Delay(2000);
    else if (i == 2)
        await Task.Delay(1000);
    else if (i == 3)
        await Task.Delay(5000);

    return i;
}

private static int ThreadFunc(int i)
{
    if (i == 1)
        Thread.Sleep(2000);
    else if (i == 2)
        Thread.Sleep(1000);
    else if (i == 3)
        Thread.Sleep(5000);

    return i;
}


在这个示例中,有两个函数TaskFuncThreadFunc,它们分别从MainFunc被调用。我很好奇为什么第二个方法似乎没有任何效果,而且似乎会被跳过。甚至Thread.Sleep(...)也似乎没有被执行。

Time comparison

正如您所看到的,ThreadFunc的总执行时间非常短,即使睡眠计时器对于两种方法都应该相同。此外,i始终设置为4。我想主线程做错了一些事情。有人能解释一下这里发生了什么吗?


这个回答解决了你的问题吗?何时使用Task.Delay,何时使用Thread.Sleep? - T.Todua
1个回答

10
问题出在作用域上。你在 Task.Run(() => TheadFunc(i)) 中使用的那个 i 不是一个新的整数,因为它是一个委托,所以 i 的值只会在 执行委托时获取一次
这导致在所有情况下,i 都是 4,因为你的 for 循环增加了它这么多。但由于你没有针对值为 4 的 if 条件,它不会使用 Thread.Sleep(...) 进行任何延迟。

是的,我亲自测试了委托作用域并完全同意。但是我仍然不明白为什么它不能与if条件threed.sleep(...)一起使用的问题的第二部分。 - west
2
@user746499 我建议你在ThreadFunc中添加一个最终的else条件 else Thread.Sleep(10000),然后看看会发生什么。 - Theodor Zoulias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接