Görev listesini iptal etme
Zaman uyumsuz konsol uygulamasının bitmesini beklemek istemiyorsanız iptal edebilirsiniz. Bu konudaki örneği izleyerek, bir web sitesi listesinin içeriğini indiren bir uygulamaya iptal ekleyebilirsiniz. Örneği her görevle ilişkilendirerek CancellationTokenSource birçok görevi iptal edebilirsiniz. Enter tuşunu seçerseniz henüz tamamlanmamış tüm görevleri iptal edebilirsiniz.
Bu öğreticinin içindekiler:
- .NET konsol uygulaması oluşturma
- İptali destekleyen zaman uyumsuz bir uygulama yazma
- sinyal iptali gösterme
Ön koşullar
Bu öğretici için aşağıdakiler gereklidir:
- .NET 5 veya üzeri SDK
- Tümleşik geliştirme ortamı (IDE)
Örnek uygulama oluşturma
Yeni bir .NET Core konsol uygulaması oluşturun. Komutunu kullanarak dotnet new console
veya Visual Studio'dan oluşturabilirsiniz. Program.cs dosyasını sık kullandığınız kod düzenleyicisinde açın.
using deyimlerini değiştirme
Mevcut using deyimlerini şu bildirimlerle değiştirin:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
Alan ekle
Sınıf tanımına Program
şu üç alanı ekleyin:
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"
};
, CancellationTokenSource bir için istenen iptalin sinyalini vermek için CancellationTokenkullanılır. , HttpClient
HTTP istekleri gönderme ve HTTP yanıtları alma özelliğini kullanıma sunar. , s_urlList
uygulamanın işlemeyi planladığı tüm URL'leri barındırır.
Uygulama giriş noktasını güncelleştirme
Konsol uygulamasının ana giriş noktası yöntemidir Main
. Mevcut yöntemi aşağıdakilerle değiştirin:
static async Task Main()
{
Console.WriteLine("Application started.");
Console.WriteLine("Press the ENTER key to cancel...\n");
Task cancelTask = Task.Run(() =>
{
while (Console.ReadKey().Key != ConsoleKey.Enter)
{
Console.WriteLine("Press the ENTER key to cancel...");
}
Console.WriteLine("\nENTER key pressed: cancelling downloads.\n");
s_cts.Cancel();
});
Task sumPageSizesTask = SumPageSizesAsync();
Task finishedTask = await Task.WhenAny(new[] { cancelTask, sumPageSizesTask });
if (finishedTask == cancelTask)
{
// wait for the cancellation to take place:
try
{
await sumPageSizesTask;
Console.WriteLine("Download task completed before cancel request was processed.");
}
catch (TaskCanceledException)
{
Console.WriteLine("Download task has been cancelled.");
}
}
Console.WriteLine("Application ending.");
}
Güncelleştirilmiş Main
yöntem artık yürütülebilir dosyaya zaman uyumsuz bir giriş noktası sağlayan Async ana değeri olarak kabul edilir. Konsola birkaç yönerge iletisi yazar, ardından konsol tuş vuruşlarını okuyacak adlı cancelTask
bir Task örnek bildirir. Enter tuşuna basılırsa çağrısı CancellationTokenSource.Cancel() yapılır. Bu, iptali işaret eder. sumPageSizesTask
Ardından değişkeni yönteminden SumPageSizesAsync
atanır. Daha sonra her iki görev de öğesine geçirilir Task.WhenAny(Task[])ve iki görevden herhangi biri tamamlandığında devam eder.
Sonraki kod bloğu, iptal işlemi işlenene kadar uygulamanın çıkmamasını sağlar. Tamamlanan ilk görev isecancelTask
sumPageSizeTask
, beklenmiştir. İptal edildiyse, beklendiğinde bir System.Threading.Tasks.TaskCanceledExceptionatar. Blok bu özel durumu yakalar ve bir ileti yazdırır.
Zaman uyumsuz toplam sayfa boyutları yöntemini oluşturma
yönteminin Main
altına yöntemini ekleyin SumPageSizesAsync
:
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");
}
yöntemi, örneği oluşturarak ve başlatarak Stopwatchbaşlar. Ardından ve içindeki her URL'de s_urlList
döngüye girerek öğesini çağırır ProcessUrlAsync
. Her yinelemede yöntemine s_cts.Token
ProcessUrlAsync
geçirilir ve kod bir Task<TResult>döndürür; burada TResult
bir tamsayıdır:
int total = 0;
foreach (string url in s_urlList)
{
int contentLength = await ProcessUrlAsync(url, s_client, s_cts.Token);
total += contentLength;
}
İşlem yöntemi ekleme
Yönteminin altına SumPageSizesAsync
aşağıdaki ProcessUrlAsync
yöntemi ekleyin:
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;
}
Herhangi bir URL için yöntemi, yanıtı olarak byte[]
almak için sağlanan örneği kullanırclient
. örneği CancellationToken ve HttpContent.ReadAsByteArrayAsync() yöntemlerine HttpClient.GetAsync(String, CancellationToken) geçirilir. token
, istenen iptal için kaydolmak için kullanılır. Url ve uzunluk konsola yazıldıktan sonra uzunluk döndürülür.
Örnek uygulama çıktısı
Application started.
Press the ENTER key to cancel...
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
https://learn.microsoft.com/dotnet 67,452
https://learn.microsoft.com/dynamics365 48,582
https://learn.microsoft.com/education 22,924
ENTER key pressed: cancelling downloads.
Application ending.
Tam örnek
Aşağıdaki kod, örnek için Program.cs dosyasının tam metnidir.
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.");
Console.WriteLine("Press the ENTER key to cancel...\n");
Task cancelTask = Task.Run(() =>
{
while (Console.ReadKey().Key != ConsoleKey.Enter)
{
Console.WriteLine("Press the ENTER key to cancel...");
}
Console.WriteLine("\nENTER key pressed: cancelling downloads.\n");
s_cts.Cancel();
});
Task sumPageSizesTask = SumPageSizesAsync();
Task finishedTask = await Task.WhenAny(new[] { cancelTask, sumPageSizesTask });
if (finishedTask == cancelTask)
{
// wait for the cancellation to take place:
try
{
await sumPageSizesTask;
Console.WriteLine("Download task completed before cancel request was processed.");
}
catch (OperationCanceledException)
{
Console.WriteLine("Download task has been cancelled.");
}
}
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;
}
}
Ayrıca bkz.
Sonraki adımlar
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin