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;
}

In this example there are two functions, TaskFunc and ThreadFunc, which are called from MainFunc seperately. I am curious as to why the second method doesn't seem to have any effect, and seems to be skipped. Not even the Thread.Sleep(...) seems to get executed.

Time comparison

As you can see, the total execution time for ThreadFunc is very short, even though the sleep timers should be same for both methods. Also, i is always set to 4. I suppose that the main thread is doing something wrong. Can someone explain what is going on here?

Ian H.
  • 3,840
  • 4
  • 30
  • 60
west
  • 346
  • 1
  • 5
  • 18
  • Does this answer your question? [When to use Task.Delay, when to use Thread.Sleep?](https://stackoverflow.com/questions/20082221/when-to-use-task-delay-when-to-use-thread-sleep) – T.Todua Jun 24 '22 at 15:48

1 Answers1

10

The issue here is scoping. The i you are using inside the Task.Run(() => TheadFunc(i)) is not a new integer, but rather, since it's a delegate, the value of i will only be retrieved once the delegate is executed.

This leads to i being 4 in all cases, since your for-loop increases it that much. But since you do not have an if-condition for a value of 4, it won't perform any delays with Thread.Sleep(...).

Ian H.
  • 3,840
  • 4
  • 30
  • 60
  • Yes, I tested it for myself about delegate scoping and totally agreed. but second part of my question still can not understand why it does not work with if condition threed.sleep(...). – west Mar 29 '20 at 15:34
  • 2
    @user746499 I suggest that you add to your `ThreadFunc` a final else condition `else Thread.Sleep(10000)`, and see what happens then. – Theodor Zoulias Mar 29 '20 at 15:45