16 Şubat 2015 Pazartesi

Task Parallel Library

Neden Task Parallel Library
Task Parallel Library (TPL) çıkmadan önce multi-threaded kod yazmak için iki seçeneğimiz vardı. Bunlar 
  • Direkt Thread sınıfını kullanmak
  • ThreadPool sınıfını kullanmaktı. 

Thread sınıfını kontrol edebiliriz. Thread'i durdurup iptal edebiliriz. ThreadPool sınıfı üzerinde ise hiç kontrolümüz yok. Verilen işin sonucunu almanın kolay bir yolu da yok. MSDN örneğinde ThreadPool'da Fibonacci serisi hesaplatma gösteriliyor. İşlerin bittiğini anlamak için dışarında bir ManualResetEvent dizisi verilmek zorunda. Ayrıca her thread hesaplamanın sonucunu yine global bir diziye yerleştiriyor. Dolayısıyla kullanması kolay bir yöntem değil.

TPL direkt Thread veya ThreadPool kullanmak yerine, daha nesne yönelimli bir yapı sunuluyor. Bu yeni çatı sayesinde geliştiriciler daha soyut kod yazabiliyorlar.

Parallel sınıfı
Bu sınıf ile PLINQ benzer oldukları için PLINQ başlıklı yazıya taşıdım.

TaskCreationOptions sınıfı
TaskCreationOptions yazısına taşıdım.

Task ve await
Continuation yazısına taşıdım.

Task sınıfı
Bu sınıf çalıştırılacak işi temsil eder.

ContinueWhenAll metodu
Aşağıdaki açıklama önemli çünkü çağıran thread bloke olup beklemiyor. Tüm işler bitince bir başka thread içinde yeni bir task çalıştırılıyor.

ContinueWith metodu
Bu metod, task bittikten sonra thread pool içinde bir başka adıma geçme imkanı sağlar. Continuation Tasks başlıklı yazıya göz atmakta fayda var. Bir başka güzel açıklamayı ise buradan aldım.
A continuation is some code that is attached to a task and executed when that task completes. Tasks have direct support for continuations via the ContinueWith method.
ContinueWith İçinde Önceki İşin Sonucuna Erişmek
Aşağıdaki örnekte ContinueWith() metoduna önceki işin parametre olarak geçtiği ve sonucuna erişilebildiği görülebiliyor.

Delay metodu
İşin geciktirilerek başlatılmasını sağlar. 
var t = Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Start");
        Task.Delay(5000).Wait();
        Console.WriteLine("Done");
    });

WaitAll metodu
Task Başlatma yazısına taşıdım. 

WhenAll metodu
Tüm işler bitince çalışacak yeni bir task yaratılır.
Task[] t = /...
Task.WhenAll (t);

TaskScheduler
Bu sınıf Task'ın hangi thread içinde çalışacağını belirtir.

FromCurrentSynchronizationContext
Task yaratılırken, yaratan thread'e erişebilmemizi sağlar.
Örneği buradan aldım.
Bir diğer örnek ise aşağıda:

TaskContinuationOptions
Bu sınıf ile Task bittikten sonra devam edilmesi için bazı koşul ve kısıtlar tanımlanabilir.

NotOnFaulted

Bu seçenek ile hatasız bitmiş bir işin devamı çalıştırılır

OnlyOnFaulted
Bu seçenek ile thread exception atarsa, hatayı yakalama imkanı oluşur. Örnek:

static void handleException(AggregateException exception)
{
    foreach (var ex in exception.Flatten().InnerExceptions)
        Console.WriteLine(ex.Message);
}

var task = Task.Factory.StartNew(() =>
{
    throw new Exception("Test");
});

task.ContinueWith(t => handleException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

OnlyOnRanToCompletion
Aşağıdaki örnekte eğer işlem iptal edilmemişse Step1, Step2 .. arka arkaya çalıştırılır.

var t = Task.Factory.StartNew(() => Step1(cancellationToken), cancellationToken)
.ContinueWith(task => Step2(cancellationToken), cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current)
.ContinueWith(task => Step3(cancellationToken), cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current);

CancellationTokenSource sınıfı
CancellationTokenSource yazısına taşıdım.







Hiç yorum yok:

Yorum Gönder