Membatalkan tugas asinkron setelah jangka waktu tertentu
Anda dapat membatalkan operasi asinkron setelah periode waktu tertentu dengan menggunakan metode CancellationTokenSource.CancelAfter, jika Anda tidak ingin menunggu operasi selesai. Metode ini menjadwalkan pembatalan tugas terkait yang tidak selesai dalam jangka waktu yang ditentukan oleh ekspresi CancelAfter
.
Contoh ini menambahkan ke kode yang dikembangkan di Batalkan daftar tugas (C#) untuk mengunduh daftar situs web dan untuk menampilkan panjang konten masing-masing.
Tutorial ini mencakup:
- Memperbarui aplikasi konsol .NET yang ada
- Menjadwalkan pembatalan
Prasyarat
Tutorial ini memerlukan hal-hal berikut:
- Anda diharapkan telah membuat aplikasi dalam tutorial Batalkan daftar tugas (C#)
- .NET 5 atau SDK yang lebih baru
- Lingkungan pengembangan terintegrasi (IDE)
Memperbarui entry point aplikasi
Ganti metode Main
yang sudah ada dengan kode berikut:
static async Task Main()
{
Console.WriteLine("Application started.");
try
{
s_cts.CancelAfter(3500);
await SumPageSizesAsync();
}
catch (OperationCanceledException)
{
Console.WriteLine("\nTasks cancelled: timed out.\n");
}
finally
{
s_cts.Dispose();
}
Console.WriteLine("Application ending.");
}
Metode Main
yang diperbarui menulis beberapa pesan instruksi ke konsol. try-catch
Dalam , panggilan untuk menjadwalkan CancellationTokenSource.CancelAfter(Int32) pembatalan. Ini akan memberi sinyal pembatalan setelah jangka waktu tertentu.
Selanjutnya, metode SumPageSizesAsync
akan ditunggu. Jika pemrosesan semua URL terjadi lebih cepat daripada pembatalan terjadwal, maka aplikasi akan berakhir. Namun, jika pembatalan terjadwal dipicu sebelum semua URL diproses, OperationCanceledException akan dilemparkan.
Contoh output aplikasi
Application started.
https://learn.microsoft.com 37,357
https://learn.microsoft.com/aspnet/core 85,589
https://learn.microsoft.com/azure 398,939
https://learn.microsoft.com/azure/devops 73,663
Tasks cancelled: timed out.
Application ending.
Contoh lengkap
Kode berikut adalah teks lengkap dari file Program.cs sebagai contoh.
using System.Diagnostics;
class Program
{
static readonly CancellationTokenSource s_cts = new CancellationTokenSource();
static readonly HttpClient s_client = new HttpClient
{
MaxResponseContentBufferSize = 1_000_000
};
static readonly IEnumerable<string> s_urlList = new string[]
{
"https://learn.microsoft.com",
"https://learn.microsoft.com/aspnet/core",
"https://learn.microsoft.com/azure",
"https://learn.microsoft.com/azure/devops",
"https://learn.microsoft.com/dotnet",
"https://learn.microsoft.com/dynamics365",
"https://learn.microsoft.com/education",
"https://learn.microsoft.com/enterprise-mobility-security",
"https://learn.microsoft.com/gaming",
"https://learn.microsoft.com/graph",
"https://learn.microsoft.com/microsoft-365",
"https://learn.microsoft.com/office",
"https://learn.microsoft.com/powershell",
"https://learn.microsoft.com/sql",
"https://learn.microsoft.com/surface",
"https://learn.microsoft.com/system-center",
"https://learn.microsoft.com/visualstudio",
"https://learn.microsoft.com/windows",
"https://learn.microsoft.com/maui"
};
static async Task Main()
{
Console.WriteLine("Application started.");
try
{
s_cts.CancelAfter(3500);
await SumPageSizesAsync();
}
catch (OperationCanceledException)
{
Console.WriteLine("\nTasks cancelled: timed out.\n");
}
finally
{
s_cts.Dispose();
}
Console.WriteLine("Application ending.");
}
static async Task SumPageSizesAsync()
{
var stopwatch = Stopwatch.StartNew();
int total = 0;
foreach (string url in s_urlList)
{
int contentLength = await ProcessUrlAsync(url, s_client, s_cts.Token);
total += contentLength;
}
stopwatch.Stop();
Console.WriteLine($"\nTotal bytes returned: {total:#,#}");
Console.WriteLine($"Elapsed time: {stopwatch.Elapsed}\n");
}
static async Task<int> ProcessUrlAsync(string url, HttpClient client, CancellationToken token)
{
HttpResponseMessage response = await client.GetAsync(url, token);
byte[] content = await response.Content.ReadAsByteArrayAsync(token);
Console.WriteLine($"{url,-60} {content.Length,10:#,#}");
return content.Length;
}
}