Directorio de artículos
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.
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:
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.
Cambie Void a Task para esperar eventos asincrónicos.
Imprima las expectativas del servicio de resultados y espere a que finalicen los eventos asincrónicos antes de ejecutarlos.
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.
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
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
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");
}
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.