C. Knight
C. Knight

Reputation: 749

Maximum number of Threads available to Tasks

I'm Trying to get my head around the async-await functionality within C#. I've written the below code to run several tasks asynchronously - currently all they do is raise an event after a certain amount of time.

public class Program
{
    public static Stopwatch Watch = new Stopwatch();

    public static void Main(string[] args)
    {
        AsyncClass asyncClass = new AsyncClass();
        asyncClass.WaitSecondsAsyncCompleted += asyncClass_WaitSecondsAsyncCompleted;
        List<Task> tasks = new List<Task>();
        Watch.Start();
        for (int i = 1; i < 6; i++)
        {
            tasks.Add(asyncClass.WaitSecondsAsync(i, Watch));
        }
        Task.WaitAll(tasks.ToArray());
        Console.ReadLine();
    }

    private static void asyncClass_WaitSecondsAsyncCompleted(int i)
    {
        Console.WriteLine("{1} : Async Method Called: waited for {0} seconds", i, Watch.ElapsedMilliseconds);
    }
}

public class AsyncClass
{
    public event Action<int> WaitSecondsAsyncCompleted;

    public async Task WaitSecondsAsync(int x, Stopwatch watch)
    {
        await Task.Run(() =>
        {   
            Thread.Sleep(x * 500); 
        });

        if (WaitSecondsAsyncCompleted != null)
        {
            WaitSecondsAsyncCompleted(x);
        }
    }
}

I'd expect a task to be completed roughly once every half a second - however this is not quite what I see. Instead the first four tasks complete on time but the final task has an extra half second delay: output of above code

This seems very strange - and the only thing I can think of is that there is a limit on the number of threads that are available to a task and that this is limit is very small and so the fifth task is having to wait for the first task to complete before it can start.

I added some extra output and increased the number of tasks to try and gain more information but I can make little sense of it - the output seems to be deterministic, some threads are reused, but also new ones are used. The delay on tasks being completed also seems to continue to grow (for instance for Task 10 I'd expect it to complete after 5 seconds, instead it stops after 8 seconds). I've attached the output below.

What I'd like to know:

output with extra debug info


Edit

Note that this question does not ask about the maximum number of tasks that can be run (Max tasks in TPL?) but rather how an effect can be seen when running as few as 5 tasks. I was under the impression that default threadPool contained many more threads than this.

Upvotes: 11

Views: 27541

Answers (1)

C. Knight
C. Knight

Reputation: 749

So, it turns out that the issue I was seeing had to do with the threadpool size. This is apparently initially set to the number of cores of the machine (https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getminthreads%28v=vs.110%29.aspx).

It can be increased, and doing so means that more of the tasks are initially run simultaneously (https://msdn.microsoft.com/en-us/library/system.threading.threadpool.setminthreads%28v=vs.110%29.aspx)

Upvotes: 8

Related Questions