Registro de devoluciones de llamada como solicitudes de cancelaciónRegister callbacks for cancellation requests
Obtenga información sobre cómo registrar un delegado que se invocará cuando una propiedad IsCancellationRequested se convierta en "true".Learn how to register a delegate that will be invoked when a IsCancellationRequested property becomes true. El valor cambia de "false" a "true" cuando se realiza una llamada a Cancel en el objeto que creó el token.The value changes from false to true when a call to Cancel on the object that created the token is made. Use esta técnica para cancelar operaciones asincrónicas que no admiten el marco de cancelación unificado de forma nativa, y para desbloquear métodos que podrían estar esperando que una operación asincrónica finalice.Use this technique for canceling asynchronous operations that do not natively support the unified cancellation framework, and for unblocking methods that might be waiting for an asynchronous operation to finish.
Nota
Cuando está habilitada la opción "Solo mi código", en algunos casos, Visual Studio se interrumpe en la línea que produce la excepción y muestra el mensaje de error "Excepción no controlada por el código de usuario".When "Just My Code" is enabled, Visual Studio in some cases will break on the line that throws the exception and display an error message that says "exception not handled by user code." Este error es benigno.This error is benign. Puede presionar F5 para continuar y ver el comportamiento de control de excepciones que se muestra en estos ejemplos.You can press F5 to continue from it, and see the exception-handling behavior that is demonstrated in the examples below. Para evitar que Visual Studio se interrumpa con el primer error, desactive la casilla "Solo mi código" en Herramientas, Opciones, Depurar, General.To prevent Visual Studio from breaking on the first error, just uncheck the "Just My Code" checkbox under Tools, Options, Debugging, General.
EjemploExample
En el ejemplo siguiente, el método CancelAsync se registra como el método que se invocará cuando se solicite la cancelación mediante el token de cancelación.In the following example, the CancelAsync method is registered as the method to be invoked when cancellation is requested through the cancellation token.
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
class CancelWithCallback
{
static void Main()
{
using var cts = new CancellationTokenSource();
var token = cts.Token;
_ = Task.Run(async () =>
{
using var client = new WebClient();
client.DownloadStringCompleted += (_, args) =>
{
if (args.Cancelled)
{
Console.WriteLine("The download was canceled.");
}
else
{
Console.WriteLine("The download has completed:\n");
Console.WriteLine($"{args.Result}\n\nPress any key to continue.");
}
};
if (!token.IsCancellationRequested)
{
using CancellationTokenRegistration ctr = token.Register(() => client.CancelAsync());
Console.WriteLine("Starting request\n");
await client.DownloadStringTaskAsync(new Uri("http://www.contoso.com"));
}
}, token);
Console.WriteLine("Press 'c' to cancel.\n\n");
if (Console.ReadKey().KeyChar == 'c')
{
cts.Cancel();
}
Console.WriteLine("\nPress any key to exit.");
Console.ReadKey();
}
}
Imports System.Net
Imports System.Threading
Friend Class CancelWithCallback
Private Shared Sub Main()
Using cts = New CancellationTokenSource()
Dim token = cts.Token
Task.Run(
Async Function()
Using client As New WebClient()
AddHandler client.DownloadDataCompleted,
Sub(__, args)
If args.Cancelled Then
Console.WriteLine("The download was canceled.")
Else
Console.WriteLine($"The download has completed:{vbLf}")
Console.WriteLine($"{args.Result}{vbLf}{vbLf}Press any key to continue.")
End If
End Sub
If Not token.IsCancellationRequested Then
Dim ctr As CancellationTokenRegistration = token.Register(Sub() client.CancelAsync())
Console.WriteLine($"Starting request{vbLf}")
Await client.DownloadStringTaskAsync(New Uri("http://www.contoso.com"))
End If
End Using
End Function, token)
Console.WriteLine($"Press 'c' to cancel.{vbLf}{vbLf}")
If Console.ReadKey().KeyChar = "c"c Then
cts.Cancel()
End If
Console.WriteLine($"{vbLf}Press any key to exit.")
Console.ReadKey()
End Using
End Sub
End Class
Si ya ha solicitado la cancelación al registrar la devolución de llamada, aún se garantiza que se llamará a la devolución de llamada.If cancellation has already been requested when the callback is registered, the callback is still guaranteed to be called. En este caso, el método CancelAsync no hará nada si no hay ninguna operación asincrónica en curso, por lo que siempre es seguro llamar al método.In this particular case, the CancelAsync method will do nothing if no asynchronous operation is in progress, so it is always safe to call the method.