Cancelación de tareas entre múltiples hilos
// Tareas concurrentes multiproceso. Después de un error, quiero notificar a otros subprocesos que se detengan. ¿Cómo? // Thread.Abort - termina el hilo; lanza una excepción al hilo actual y luego termina la tarea; el hilo es un recurso del sistema operativo y puede no detenerse de inmediato // La tarea no puede terminar la tarea externamente, y solo puede terminar por sí misma (Dios puede derrotarse a sí mismo) // cts tiene un atributo bool La inicialización IsCancellationRequested es falsa // se vuelve verdadera después de llamar al método Cancel (no se puede volver a cambiar), puede repetir cancelar try { CancellationTokenSource cts = new CancellationTokenSource (); List <Task> taskList = new List <Task > (); para ( int i = 0 ; i < 50 ; i ++ ) { string name = $ " btnThreadCore_Click_ {i} " ; taskList.Add (Task.Run (() => { try { if (! cts.IsCancellationRequested) Console.WriteLine ($ " Esto es {nombre} 开始 ThreadId = {Thread.CurrentThread.ManagedThreadId.ToString ( " 00 " )} " ); Thread.Sleep ( nuevo Random (). Next ( 50 , 100 )); if(name.Equals ( " btnThreadCore_Click_11 " )) { lanzar una nueva excepción ( " btnThreadCore_Click_11 异常" ); } else if (name.Equals ( " btnThreadCore_Click_12 " )) { lanzar una nueva excepción ( " btnThreadCore_Click_12 异常" ); } else if (name.Equals ( " btnThreadCore_Click_13 " )) { cts.Cancel (); } if (! cts.IsCancellationRequested) { Console.WriteLine ($ " Esto es {nombre} 成功 结束 ThreadId = {Thread.CurrentThread.ManagedThreadId.ToString ( " 00 " )} " ); } else { Console.WriteLine ($ " Esto es {nombre} 中途 停止 ThreadId = {Thread.CurrentThread.ManagedThreadId.ToString ( " 00 ")} " ); return ; } } catch (Exception ex) { Console.WriteLine (ex.Message); cts.Cancel (); } }, cts.Token)); // El token entrante se cancelará después de Cancelar Tarea
} // 1 prepare cts 2 try-catch-cancel 3 La acción debe juzgar IsCancellationRequested en cualquier momento // detenerse lo antes posible, debe haber una demora, terminará en el enlace de juicio Task.WaitAll (taskList.ToArray ()); // Si el hilo aún no ha Comienza, ¿puedes detenerlo? // 1 Inicie el hilo para pasar la captura de excepción Token 2. // Las tareas que no se iniciaron cuando Cancelado no se iniciarán; también arroje una excepción, cts.Token.ThrowIfCancellationRequested } catch (AggregateException aex) { foreach ( excepción var en aex. InnerExceptions) {Console.WriteLine (exception.Message);}} catch (Exception ex) {Console.WriteLine (ex.Message);}
Bloqueo de memoria multiproceso
// 1 Lock resuelve conflictos de múltiples hilos // Lock es azúcar sintáctico, Monitor.Enter, ocupa una referencia, otros hilos solo pueden esperar // el bloqueo recomendado es un objeto privado de solo lectura estática, // A no puede ser Nulo, puede compilarse No se puede ejecutar; // B no recomienda bloquear (esto), si necesita usar una instancia externa, entrará en conflicto Test test = new Test (); Task.Delay ( 1000 ) .ContinueWith (t => { lock (test) { Console .WriteLine ( " ********* Start ********** " ); Thread.Sleep ( 5000 ); Console.WriteLine ( " ********* End ********** " ); } }); test.DoTest (); // C no debe ser una cadena; la cadena está asignada en la memoria Lo anterior se reutiliza y no habrá conflictos. // El código en D Lock no debería ser demasiado. Aquí está la prueba de prueba de un solo subproceso = nueva Prueba (); string student = " boiled fish " ; Task.Delay ( 1000 ) .ContinueWith (t => { lock (estudiante) { Console.WriteLine ( "********* Inicio ********** " ); Thread.Sleep ( 5000 ); Console.WriteLine ( " ********* Fin ***** ***** " ); } }); test.DoTestString (); pública vacío DoTestString () { Lock ( el presente .Nombre) // llamadas recursivas, bloquear este será un punto muerto el 98% dijo que no lo haría?! Deadlock! // Este es el mismo hilo, esta referencia está ocupada por este hilo { Thread.Sleep ( 500 ); esto.iDoTestNum ++ ; if (DateTime.Now.Day < 28 && this .iDoTestNum < 10 ) { Console.WriteLine ($ " Esto es {this.iDoTestNum} 次 {DateTime.Now.Day} " ); this .DoTestString (); } else { Console.WriteLine ( " 28 号 , 课程 结束 !!" ); } } } private int iDoTestNum = 0; cadena privada Nombre = " Pescado hervido " ;
Colección segura de múltiples hilos
System.Collections.Concurrent.ConcurrentQueue <int>