Registrera återanrop för annulleringsbegäranden
Lär dig hur du registrerar ett ombud som anropas när en IsCancellationRequested egenskap blir sann. Värdet ändras från false till true när ett anrop till Cancel på objektet som skapade token görs. Använd den här tekniken för att avbryta asynkrona åtgärder som inte har inbyggt stöd för det enhetliga annulleringsramverket och för avblockeringsmetoder som kan vänta på att en asynkron åtgärd ska slutföras.
Kommentar
När "Just My Code" är aktiverat bryts Visual Studio i vissa fall på raden som genererar undantaget och visar ett felmeddelande som säger "undantag hanteras inte av användarkod". Det här felet är godartat. Du kan trycka på F5 för att fortsätta från den och se det beteende för undantagshantering som visas i exemplen nedan. Om du vill förhindra att Visual Studio bryter mot det första felet avmarkerar du kryssrutan "Just My Code" under Verktyg, Alternativ, Felsökning, Allmänt.
Exempel
I följande exempel CancelAsync registreras metoden som den metod som ska anropas när annullering begärs via annulleringstoken.
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
Om annullering redan har begärts när återanropet har registrerats garanteras återanropet fortfarande att anropas. I det här fallet CancelAsync gör metoden ingenting om ingen asynkron åtgärd pågår, så det är alltid säkert att anropa metoden.