【问题标题】:Task.Delay vs Thread.Sleep differenceTask.Delay 与 Thread.Sleep 的区别
【发布时间】:2020-03-29 14:11:07
【问题描述】:
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(...) 似乎都没有被执行。

如您所见,ThreadFunc 的总执行时间非常短,尽管两种方法的睡眠计时器应该相同。另外,i 总是设置为 4。我想主线程做错了什么。有人可以解释这里发生了什么吗?

【问题讨论】:

    标签: c# multithreading async-await task


    【解决方案1】:

    这里的问题是范围界定。您在Task.Run(() =&gt; TheadFunc(i)) 中使用的i 不是一个新整数,而是因为它是一个委托,所以i 的值只会在委托执行后检索

    这导致i 在所有情况下都是4,因为您的for-loop 增加了很多。但是由于您没有值为 4 的if-条件,它不会对Thread.Sleep(...) 执行任何延迟。

    【讨论】:

    • 是的,我为自己测试了委托范围并完全同意。但是我的问题的第二部分仍然无法理解为什么它不适用于 if 条件threed.sleep(...)。
    • @user746499 我建议你在ThreadFunc 中添加一个最终的else 条件else Thread.Sleep(10000),然后看看会发生什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2019-11-12
    • 2020-06-29
    • 1970-01-01
    相关资源
    最近更新 更多