複数のスレッド間のタスクのキャンセル
// マルチスレッドの同時タスクです。障害が発生した後、他のスレッドに停止を通知します。方法 // Thread.Abort-スレッドを終了します;現在のスレッドに例外をスローしてからタスクを終了します;スレッドはOSリソースであり、すぐに停止しない場合 があります// タスクはタスクを外部で終了できず、自分自身のみを終了できます(神は自分自身を倒すことができます) // ctsはbool属性を持っていますIsCancellationRequested初期化はfalse // Cancelメソッドを呼び出した後にtrueになり(元に戻すことはできません)、キャンセルを再 試行できます { CancellationTokenSource cts = new CancellationTokenSource(); リスト <Task> taskList = new List <Task> (); for(int i = 0 ; i < 50 ; i ++ ) { 文字列名= $ " btnThreadCore_Click_ {i} " ; taskList.Add(Task.Run(() => { 試す { if(!cts.IsCancellationRequested) Console.WriteLine($ " これは{名前}です开開始ThreadId = {Thread.CurrentThread.ManagedThreadId.ToString(" 00 " )} " ); Thread.sleep(新しいランダム()次(。50、100 )); if(name.Equals(" btnThreadCore_Click_11 " )) { 新しい Exception(" btnThreadCore_Click_11异常" );をスローします。 } else if(name.Equals(" btnThreadCore_Click_12 " )) { 新しい Exception(" btnThreadCore_Click_12异常" );をスローします。 } else if(name.Equals(" btnThreadCore_Click_13 " )) { cts.Cancel(); } if(!cts.IsCancellationRequested) { Console.WriteLine($ " これは{name}成功结束ですThreadId = {Thread.CurrentThread.ManagedThreadId.ToString(" 00 " )} " ); } そうしないと { Console.WriteLine($ " これは{name}中途停止ThreadId = {Thread.CurrentThread.ManagedThreadId.ToString(" 00 " )} "です); 戻る; } } キャッチ(例外例) { Console.WriteLine(ex.Message); cts.Cancel(); } }、cts.Token)); //受信トークンは、キャンセル後にすべてのタスクをキャンセルします
} // 1 prepare cts 2 try-catch-cancel 3アクションはいつでもIsCancellationRequestedを判断する必要があります// できるだけ早く停止し、遅延がなければならず、判断リンクで終了します Task.WaitAll(taskList.ToArray()); // スレッドがまだない場合始めて、止めてもらえますか?@ 1トークン2異常転写把持スレッドを開始// タスクが起動していないキャンセルShihaiに開始されていないと、例外がスローされ、cts.Token.ThrowIfCancellationRequested } キャッチ(AggregateException AEX){ foreachの(VARの例外でAEX。 InnerExceptions){Console.WriteLine(exception.Message);}} catch (Exception ex){Console.WriteLine(ex.Message);}
マルチスレッドメモリロック
// 1ロックはマルチスレッドの競合を解決します // ロックは構文糖、Monitor.Enter、参照を占有し、他のスレッドは待機するだけです // 推奨されるロックはプライベートな静的な読み取り専用オブジェクトです // // Nullにすることはできず、コンパイルできます実行できません; // Bはロック(これ)を推奨しません。 外部でインスタンスを使用する必要がある場合、競合します Test test = new Test(); Task.Delay(1000).ContinueWith(t => { ロック(テスト) { Console.WriteLine(" ********* Start ********** " ); Thread.Sleep(5000 ); Console.WriteLine(" ********* End ********** " ); } }); test.DoTest(); // Cは文字列であってはなりません。文字列はメモリ割り当てで再利用され、競合します。// D Lockにコードが多すぎないようにしてください。 シングルスレッドの Test test = new Test(); string student = " boiled fish " ; Task.Delay(1000).ContinueWith(t => { ロック(学生) { Console.WriteLine(" ********* Start ********** " ); Thread.Sleep(5000 ); Console.WriteLine(" ********* End ********** " ); } }); test.DoTestString(); public void DoTestString() { lock(this .Name) // 再帰呼び出し、このデッドロックをロックしますか?98%が「はい」と答えました。デッドロックなし! // これは同じスレッドであり、この参照はこのスレッドによって占有されています { Thread.Sleep(500 ); this .iDoTestNum ++ ; if(DateTime.Now.Day < 28 && this .iDoTestNum < 10 ) { Console.WriteLine($ " これは{this.iDoTestNum}次{DateTime.Now.Day}です" ); this .DoTestString(); } そうしないと { Console.WriteLine(" 28、コースの終わり!! " ); } } } private int iDoTestNum = 0 ; private string Name = " Boiled Fish " ;
マルチスレッドセーフコレクション
System.Collections.Concurrent.ConcurrentQueue <int>