web-dev-qa-db-ja.com

タスクで使用可能なスレッドの最大数

私はC#内の非同期待機機能を理解しようとしています。以下のコードを書いて、いくつかのタスクを非同期で実行します-現在、それらが行うことは、一定時間後にイベントを発生させることだけです。

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

おおよそ0.5秒に1回タスクが完了すると思いますが、これは私が見ているものとはかなり異なります。代わりに、最初の4つのタスクは時間どおりに完了しますが、最後のタスクにはさらに0.5秒の遅延があります。 output of above code

これは非常に奇妙に見えます-そして私が考えることができる唯一のことは、タスクが利用できるスレッドの数に制限があり、これは非常に小さいため、5番目のタスクは最初のタスクを待たなければならないということです開始する前に完了するタスク。

追加の出力をいくつか追加し、より多くの情報を取得するためにタスクの数を増やしましたが、ほとんど意味がありません。出力は確定的であるようで、一部のスレッドは再利用されていますが、新しいスレッドも使用されています。完了したタスクの遅延も増え続けているようです(たとえば、タスク10の場合、5秒後に完了するのではなく、8秒後に停止するはずです)。以下の出力を添付しました。

私が知りたいこと:

  • この特定の例で何が起こっているのか誰か知っていますか?
  • 利用可能なスレッドの制限は、ここで効果を発揮するのに十分小さいですか?
  • 非同期タスクがすぐに開始することが保証されていないと思いますが、ここでは、予期していなかった他の確定的なプロセスが行われているようです。誰か知ってる?

output with extra debug info


編集する

この質問では、実行できるタスクの最大数( TPLの最大タスク数 )については尋ねられませんが、わずか5つのタスクを実行したときに効果がどのように見えるかを確認してください。デフォルトのthreadPoolにはこれよりも多くのスレッドが含まれているという印象を受けました。

11
C. Knight

したがって、私が見ている問題はスレッドプールのサイズに関係していることがわかりました。これは明らかに、最初はマシンのコア数に設定されています( 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

5
C. Knight