CancellationToken Nedir, Nerelerde Kullanılır?

Merhaba,

Bu yazımızda, programlamada, yapılmakta olan işlemlerin (özellikle asenkron işlemlerin) iptal edilmesi durumunda kullandığımız oldukça basit bir yapı olan Cancellation Token konusunu inceleyeceğim.

Cancellation Token, uzun sürebilen asenkron işlemleri iptal etmek için kullanılan bir .NET sınıfıdır. “İptal Tokenı” anlamına gelen Cancellation Token yapılmakta olan upload gibi sistemi yorucu veya veri trafiğini arttırıcı bir işlemin iptal edilip edilmediğini belirli aralıklarla kontrol ederek, eğer iptal edilmişse işlemi durdurma ilkesine dayanır. Bu sayede işlemin boşuna devam etmesine izin verilmez ve sistem kaynakları israf edilmemiş olur.

Oldukça basit bir mantığa dayanan bu sınıfın yaptığı işi isterseniz kendi oluşturacağınız bir yapıyla da tasarlayabilirsiniz. Ancak .NET’te tercih edilen kullanım bu şekildedir.

Bir .NET Console uygulamasında aşağıdaki gibi bir kod bloğu düşünün.

using System;

async void IslemAsync(CancellationToken token)
{
    for (int i = 1; i <= 10; i++)
    {
        // İşlemin iptal edilip edilmediği her adımda kontrol edilir.
        token.ThrowIfCancellationRequested();

        Console.WriteLine($"Adım {i}");
        await Task.Delay(1000); // Bir saniye bekle
    }
}

// CancellationToken'ı oluşturan sınıf.
var tokenSource = new CancellationTokenSource();

// Asenkron işlemin başlatılması ve token'ın gönderilmesi.
IslemAsync(tokenSource.Token);

Thread.Sleep(3000);     // Asenkron işlem devam ededursun, üç saniye bekle
tokenSource.Cancel();   // İptal isteği gönder

Görüleceği üzere IslemAsync() devam ederken, her bir döngüde token için bir iptal talebi alınıp alınmadığı kontrol ediliyor. Böylece kullanıcının bir iptal butonuna tıklaması veya tarayıcıyı kapatması gibi bir durumda bir CancellationToken tetiklenerek işlem durdurulabiliyor.

İstersek ThrowIfCancellationRequested() metodunu çağırmak yerine if ve try-catch blokları kullanarak ilgili exception‘ı kendimiz de fırlatabiliriz. Bu örneği de senkron bir metod kullanarak vereceğim. Bu durumda kodlarımız aşağıdaki gibi olur.

using System;

void Islem(CancellationToken token)
{
    for (int i = 1; i <= 10; i++)
    {
        // İşlemin iptal edilip edilmediği bir if bloğuyla kontrol ediliyor.
        if (token.IsCancellationRequested)
        {
            Console.WriteLine("İptal isteği geldi. İşlem durduruluyor.");
            throw new OperationCanceledException();
        }

        Console.WriteLine($"Adım {i}");
        Thread.Sleep(1000); // Bir saniye bekle
    }
}

var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;

// İşlemin asenkron olarak başlatılması.
var task = Task.Run(() => Islem(token), token);

// Kullanıcının bir müddet sonra iptal etmek istediğini varsayalım.
Console.WriteLine("İptal etmek için Enter'a basın.");
Console.ReadLine();

// Enter'a basınca iptal isteği gönderilir.
tokenSource.Cancel();

try
{
    await task;
}
catch (OperationCanceledException)
{
    Console.WriteLine("İşlem iptal edildi.");
}

Fark ettiyseniz burada, senkron bir metodu Task sınıfının yardımıyla asenkron olarak tetikledik. Uygun senaryoyu elbette kendiniz belirleyeceksiniz.

Umarım yararlı olmuştur. Bir sonraki yazımızda görüşmek üzere…

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir