Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task.Delay vs Thread.Sleep difference

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?

like image 562
west Avatar asked Mar 29 '20 14:03

west


People also ask

What is the difference between a Task and a thread?

A task is something you want done. A thread is one of the many possible workers which performs that task. In . NET 4.0 terms, a Task represents an asynchronous operation.

What is Task delay?

The Delay method is typically used to delay the operation of all or part of a task for a specified time interval. Most commonly, the time delay is introduced: At the beginning of the task, as the following example shows.

What is the alternative for thread sleep?

Alternative: use wait() and notify() Now we have to refactor our test as well. After we start the counter we need to block the thread running the test until the counting is over.

Does Task delay start a new thread?

Task. Delay does not create new Thread, but still may be heavy, and no guaranties on order of execution or being precise about deadlines.


1 Answers

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(...).

like image 97
Ian H. Avatar answered Nov 15 '22 03:11

Ian H.