C#スレッド、タスク、同期


C#スレッド、タスク、同期
  • スレッド、タスク、および同期
  • スレッド概要
  • 非同期委任
  • スレッド、タスク、同期
    スレッドの使用にはいくつかの理由があります.アプリケーションからネットワーク呼び出しを行うには一定の時間がかかると仮定します.ユーザは、ユーザ境界を分割したくなく、サーバから応答が返されるまでユーザを待たせる.ユーザーは、他の操作を同時に実行したり、サーバに送信されたリクエストをキャンセルしたりすることができます.これらはスレッドを使用して実現できます.
    ファイル、データベース、またはネットワークへのアクセスに時間がかかるため、待機するすべての操作について、新しいスレッドを起動し、他のタスクを完了できます.密集型のタスクを処理しても、スレッドは役に立ちます.1つのプロセスの複数のスレッドは、異なるCPU上、またはマルチコアCPUの異なるコア上で同時に実行することができる.
    また、複数のスレッドを実行する際の問題にも注意する必要があります.同時に実行できますが、スレッドが同じデータにアクセスすると問題が発生しやすくなります.同期メカニズムを実装する必要があります.
    スレッドの概要
    スレッドは、プログラム内の独立した命令フローです.C#を使用してタスクプログラムを作成する場合、エントリポイント:Main()メソッドがあります.このメソッドが戻るまで、プログラムはMain()メソッドの最初の文から実行されます.
    このプログラム構造は、識別可能なタスクシーケンスを持つプログラムに非常に適しているが、プログラムは複数のタスクを同時に完了する必要があることが多い.スレッドはクライアントとサーバ側に適用されます.Visual StudioエディタでC#コードを入力すると、バックグラウンドスレッドで完了する欠落したセミコロンや他の構文エラーを下線で示すコードが分析されます.Microsoft Wordのスペルチェックも同じことをします.1つのスレッドはユーザー入力を待機し、もう1つのスレッドはバックグラウンド検索を行います.3番目のスレッドは書き込みデータを一時ファイルに格納し、4番目のスレッドはインターネットから他のデータをダウンロードします.
    サーバ上で実行されるアプリケーションで、リスナースレッドと呼ばれるクライアント要求を待つスレッド.リクエストを受信すると、別のワークスレッドに渡し、クライアントとの通信を継続します.リスナースレッドはすぐに戻り、次のクライアントから送信された次のリクエストを受信します.
    プロセスには、Windowハンドル、ファイルシステムハンドル、その他のカーネルオブジェクトなどのリソースが含まれます.各プロセスには仮想メモリが割り当てられています.1つのプロセスには少なくとも1つのスレッドが含まれます.オペレーティングシステムはスレッドをスケジュールします.スレッドには、優先度、実際に処理されているプログラムの位置カウンタ、ローカル変数を格納するスタックがあります.各スレッドには独自のスタックがありますが、プログラムコードのメモリとスタックは1つのプロセスのすべてのスレッドで共有されます.これにより、プロセスのすべてのスレッド間の通信が非常に速くなります.プロセスのすべてのスレッドは同じ仮想メモリにアドレスされます.しかし、複数のスレッドが同じメモリ位置を変更できるため、処理が困難になります.
    プロセス管理のリソースには、少なくとも1つのスレッドを含む仮想メモリとWindowハンドルが含まれます.スレッド時にプログラムを実行するために必要です.
    非同期委任
    スレッドを作成する簡単な方法は、委任を定義し、非同期で呼び出すことです.依頼はメソッドのタイプの安全な参照です.Delegateクラスは、非同期呼び出しメソッドもサポートします.バックグラウンドでは、Delegateクラスがタスクを実行するスレッドを作成します.
    スレッドプールを使用して非同期タスクを完了するように依頼します.
    依頼の非同期特性を説明するために,実行が完了するまでに一定の時間がかかる方法から開始する.TakesAWhile()メソッドは、Threadを呼び出すため、少なくとも2番目の変数を介して伝達されるミリ秒数が必要である.Sleep()メソッド.
    static int TakeAWhile(int data, int ms)	
    {
    	Console.WriteLine("TakeAWhile started");
    	Thread.Sleep(ms);
    	Console.WriteLine("TakeAWhile completed");
    	return ++data;
    }

    このメソッドを委任から呼び出すには、次のTakeAWhileDelegate()メソッドに示すように、同じパラメータと戻りタイプの委任を定義する必要があります.
    public delegate int TakesAWhileDelegate(int data, int ms);

    異なるテクノロジーを使用して、委任を非同期で呼び出し、結果を返すことができます.