Task does not wait up to the wait time

I have created a task and provided the wait time to the task.wait() method, but the task does not wait up to the provided time and return before the wait time with completed status false.

using System;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main(string[] args)
    {
        for(int i = 0 ; i < 10 ; i++)
        {
            int localValue = i;
            Task.Factory.StartNew(() => ProcessTask(localValue));
        }
        Console.ReadKey();
    }

    private static void ProcessTask(int thread)
    {
        var task = Task<int>.Factory.StartNew(() => GetSomeValue());
        task.Wait(2000);

        if(task.IsCompleted)
        {
            Console.WriteLine("Completed Thread: " + thread);
        }
        else
        {
            Console.WriteLine("Not Completed Thread " + thread);
        }
    }

    private static int GetSomeValue()
    {
        Thread.Sleep(400);
        return 5;
    }
}

Update:

I have updated the code. When I have run this code I got the following output.

enter image description here

Only two tasks are completed out of 10. so I want to know what is the issue with this code?

Note: I am running this code in 4.5.2 frameworks.

Jon Skeet
people
quotationmark

The problem isn't that Task.Wait isn't waiting long enough here - it's that you're assuming that as soon as you call Task.Factory.StartNew() (which you should almost never do, btw - use Task.Run instead), the task is started. That's not the case. Task scheduling is a complicated topic, and I don't claim to be an expert, but when you start a lot of tasks at the same time, the thread pool will wait a little while before creating a new thread, to see if it can reuse it.

You can see this if you add more logging to your code. I added logging before and after the Wait call, and before and after the Sleep call, identifying which original value of i was involved. (I followed your convention of calling that the thread, although that's not quite the case.) The log uses DateTime.UtcNow with a pattern of MM:ss.FFF to show a timestamp down to a millisecond.

Here's the output of the log for a single task that completed:

12:01.657: Before Wait in thread 7
12:03.219: Task for thread 7 started
12:03.623: Task for thread 7 completing
12:03.625: After Wait in thread 7

Here the Wait call returns after less than 2 seconds, but that's fine because the task has completed.

And here's the output of the log for a single task that didn't complete:

12:01.644: Before Wait in thread 6
12:03.412: Task for thread 6 started
12:03.649: After Wait in thread 6
12:03.836: Task for thread 6 completing

Here Wait really has waited for 2 seconds, but the task still hasn't completed, because it only properly started just before the Wait time was up.

people

See more on this question at Stackoverflow