Explicación detallada de las tareas de tareas de C#

Prefacio

Task es una encapsulación de Thread y tiene un diseño extremadamente optimizado, lo que nos hace más conveniente controlar los threads.

Tarea

La declaración de tarea se ve así:

public static  Task Sleep()
{
    
    

}

La tarea es un tipo

valor de retorno

La declaración directa de Tarea requiere un valor de retorno.
Insertar descripción de la imagen aquí

Regresar sin parámetros

public static  Task Sleep(int second)
{
    
    
    
    return Task.CompletedTask;
}

Volver con parámetros

 public static  Task<T> Sleep()
 {
    
    
     return Task.FromResult(T);
 }
//举例,返回参数只能唯一,除非使用元祖
 public static  Task<string> Sleep()
 {
    
    
     return Task.FromResult("Hello world!");
 }

Utilice Task.Result para obtener el valor de retorno


var res = Sleep().Result;

asíncrono y espera

async y await son controles para eventos asincrónicos, lo que nos facilita el control de eventos asincrónicos.

valor de retorno

Puede establecer el valor de retorno directamente después de usar async

///有参返回
 public static async  Task<string> Sleep()
 {
    
    

     return "Hello world";
 }
 ///无参返回
  public static async  Task Sleep()
 {
    
    
 }

Usar con espera

La espera de eventos asincrónicos utiliza el método de espera

        public static async Task Sleep(int second)
        {
    
    
            await Task.Delay(second * 1000);

            Console.WriteLine($"等待{
      
      second}s");
        }
        static void Main(string[] args)
        {
    
    
            Sleep(3);
            Sleep(2);
            Sleep(1);
            Console.WriteLine("运行完毕");
            //使用键盘键入事件阻塞主进程,主进程结束程序会立即退出
            Console.ReadKey();

        }

Imprime el resultado:
Insertar descripción de la imagen aquí

El resultado de la impresión muestra:

  • El evento de sincronización finaliza primero.
  • Los eventos asincrónicos no se bloquean entre sí, 3, 2, 1 comienzan al mismo tiempo, espere a que 3, 2, 1 imprima 1, 2, 3.

Transformación asíncrona principal

El programa principal está vacío y no puede esperar.

Insertar descripción de la imagen aquí
Cambie Void a Task para esperar eventos asincrónicos.
Insertar descripción de la imagen aquí
Imprima las expectativas del servicio de resultados y espere a que finalicen los eventos asincrónicos antes de ejecutarlos.
Insertar descripción de la imagen aquí

Tarea avanzada

C#Tarea Cancelar Ejecución de tarea CancellationTokenSource
C# Tarea Pausar y cancelar

Hilo de tarea cancelado

El subproceso solía tener el método Abort() para destruir el subproceso por la fuerza, pero este método se utilizó por grandes problemas de seguridad y ha quedado obsoleto.

Insertar descripción de la imagen aquí
Los subprocesos no se pueden destruir directamente, solo se pueden cancelar lanzando una excepción.

//声明token
var tokenSource = new CancellationTokenSource();
//注册异常抛出
tokenSource.Token.ThrowIfCancellationRequested();
//注册取消事件回调
tokenSource.Token.Register(() =>
{
    
    
    Console.WriteLine("线程已被取消");
});



。。。。。。别的地方的代码
//取消token,那么之前写ThrowIfCancellationRequested的地方会直接结束
tokenSource.Cancel();

caso de prueba

Una función de bucle infinito simple que devuelve un token durante el tiempo de ejecución y se usa para salir directamente del programa.

static async Task Main(string[] args)
{
    
    

    var token = Loop();
    //等待3s抛出异常
    await Task.Delay(1000 * 3);
    Console.WriteLine("任务完成!");

    token.Cancel();
    Console.ReadKey();

}

/// <summary>
/// 循环等待
/// </summary>
/// <returns></returns>
public static CancellationTokenSource Loop()
{
    
    
    var tokenSource = new CancellationTokenSource();
    Console.WriteLine("任务开始!");
    tokenSource.Token.Register(() =>
    {
    
    
        Console.WriteLine("线程已被取消");
    });
    var count = 0;
    Task.Run(async () =>
    {
    
    
        while (true)
        {
    
    
           await Task.Delay(1000);
           //抛出异常,直接结束线程
            tokenSource.Token.ThrowIfCancellationRequested();
            count++;
            Console.WriteLine(count);
        }
    });
    return tokenSource;
}

Imprimir resultados

Insertar descripción de la imagen aquí

También es más seguro de usar.

Configuración de tiempo de espera

tokenSource.CancelAfter es el método de tiempo de espera.
CancelAfter(1000): tiempo de espera después de 1000 milisegundos

 static async Task Main(string[] args)
 {
    
    
     var token = Loop();
     ///3000毫秒后取消
     token.CancelAfter(1000*3);
     Console.ReadKey();

 }


 /// <summary>
 /// 循环等待
 /// </summary>
 /// <returns></returns>
 public static CancellationTokenSource Loop()
 {
    
    
     var tokenSource = new CancellationTokenSource();
     Console.WriteLine("任务开始!");
     tokenSource.Token.Register(() =>
     {
    
    
         Console.WriteLine("线程已被取消");
     });
     var count = 0;
     Task.Run(async () =>
     {
    
    
         while (true)
         {
    
    
             await Task.Delay(1000);
             tokenSource.Token.ThrowIfCancellationRequested();
             count++;
             Console.WriteLine(count);
         }
     });
     return tokenSource;
 }

Pausa y reanudación del hilo.

La suspensión del hilo también se controla mediante una clase, ManualResetEvent. Al igual que la destrucción de subprocesos, no se puede pausar directamente porque no es seguro pausar directamente.

//声明,false为默认阻塞,true为不阻塞
var resetEvent = new ManualResetEvent(false);
//暂停,通过WaitOne方法来阻塞线程,通过Set和Reset来设置是否阻塞
resetEvent.WaitOne();
//阻塞暂停
resetEvent.Set()
//取消阻塞,继续
resetEvent.Reset()

caso de prueba
  static async Task Main(string[] args)
  {
    
    

      var canStop = CanStop();
      //等待3s抛出异常
      Console.WriteLine("等待3s启动");
      await Task.Delay(1000 * 3);
      Console.WriteLine("启动!");
      canStop.Set();
      
      Console.WriteLine("等待3s暂停");
      await Task.Delay(3000);
      Console.WriteLine("暂停!");
      canStop.Reset();

      Console.ReadKey();

  }
   public static ManualResetEvent CanStop()
 {
    
    
     var resetEvent = new ManualResetEvent(false);
     var count = 0;
     Task.Run(async () =>
     {
    
    
         while (true)
         {
    
    
             resetEvent.WaitOne();
             await Task.Delay(1000);
             
             count++;
             Console.WriteLine(count);
         }
     });
     return resetEvent;

 }

La multitarea es la más rápida

await Task.WhenAny(Task1,Task2,Task3)
solo esperará la más rápida.

        static async Task Main(string[] args)
        {
    
    
            await Task.WhenAny(Sleep(1),Sleep(2),Sleep(3));
            
            Console.WriteLine("运行结束");
            Console.ReadKey();

        }

        public async static Task Sleep(int second)
        {
    
    
            await Task.Delay(second*1000);

            Console.WriteLine($"等待{
      
      second}s");
        }

resultado de la operación

Insertar descripción de la imagen aquí

Multitarea todo esperando

        static async Task Main(string[] args)
        {
    
    
            await Task.WhenAll(Sleep(1), Sleep(2), Sleep(3));

            Console.WriteLine("运行结束");
            Console.ReadKey();

        }

        public async static Task Sleep(int second)
        {
    
    
            await Task.Delay(second*1000);

            Console.WriteLine($"等待{
      
      second}s");
        }

Insertar descripción de la imagen aquí

en conclusión

El control de los subprocesos asincrónicos es extremadamente importante. Las tareas también se pueden utilizar junto con los delegados para tener un mayor control sobre la ejecución del programa.

Supongo que te gusta

Origin blog.csdn.net/qq_44695769/article/details/133382380
Recomendado
Clasificación