任务可用的最大线程数

C. *_*ght 8 c# multithreading task threadpool async-await

我试图了解C#中的async-await功能.我编写了下面的代码来异步运行几个任务 - 目前他们所做的只是在一段时间后引发一个事件.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望每半秒大约完成一次任务 - 但这不是我所看到的.相反,前四个任务按时完成,但最终任务有一个额外的半秒延迟: 上述代码的输出

这看起来很奇怪 - 我唯一能想到的是,任务可用的线程数量有限制,这个限制非常小,因此第五个任务是必须等待第一个任务在开始之前完成.

我添加了一些额外的输出并增加了尝试获取更多信息的任务数量,但我对此几乎没有意义 - 输出似乎是确定性的,一些线程被重用,但也使用了新的.完成任务的延迟似乎也在继续增长(例如,对于任务10,我希望它在5秒后完成,而不是在8秒后停止).我附上了下面的输出.

我想知道的是什么:

  • 有谁知道这个特定例子中发生了什么?
  • 线程上的限制是否足够小以在此处产生影响?
  • 我假设异步任务不能保证立即启动,但似乎还有一些其他确定性过程在这里发生,这是我没想到的.有谁知道那是什么?

带有额外调试信息的输出


编辑

请注意,这个问题不会询问可以运行的最大任务数(TPL中的最大任务数?),而是在运行少至5个任务时如何看到效果.我的印象是默认的threadPool包含的线程比这个多得多.

C. *_*ght 5

所以,事实证明我所看到的问题与线程池大小有关.这显然是初始设置为机器的核心数(https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getminthreads%28v=vs.110%29.aspx).

它可以增加,这样做意味着更多的任务最初同时运行(https://msdn.microsoft.com/en-us/library/system.threading.threadpool.setminthreads%28v=vs.110%29 .aspx)