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.

Consulte tambiénSee also