C# ile Paralel Programlama -5 (Task koordinasyonu)

İlker Erhalim
2 min readJan 11, 2021
Tasklerin belirli bir sıra ile çalışmasını temsil eden zincir görseli.
Joey Kyber adlı kişinin Pexels’daki fotoğrafı

Paralel bir uygulama geliştirirken tasklerin belirli bir sıra ile çalışmasına, bir task içerisinde oluşturulan bir veriye başka bir task içerisinde erişmeye ihtiyaç duyabiliriz. Bunun gibi ihtiyaçlar için .net framework üzerinde birden fazla çözüm mevcut.

Continuation

Bir işin tamamlanmasının ardından yeni bir işe başlanması olarak özetleyebiliriz, .net ortamında bunu sağlamak için Task sınıfı örneğindeki ContinueWith metodunu ya da ContinueWhenAny metodunu kullanabiliriz.

Yukarıdaki örnekte task1 tamamlandıktan sonra task2 çalışmaya başlayacak ve completedTask parametresi üzerinden dönen değere erişebilecek.

Yukarıdaki örnekte task3 ün çalışması için task1 ve task2 nin çalışmayı tamamlaması gerekiyor, task1 ve task2 hangi sırada çalışırsa çalışsın taskList içerisinde ki sıralama task1 -> task2 şeklinde olacaktır. Bunun sebebi taskList koleksiyonunun ContinueWhenAll metoduna verilen sıralama ile dolmasıdır.

Bir task içerisinden exception fırlaması durumunda, arkasından tetiklenen task yine de çalışır, ancak böyle bir senaryoda task içerisindeki Result a erişilmek istendiğinde hata alınır, ya da ortak erişilen bir kaynak öncül task tarafından okunamadığı/değiştirilemediği için ardık task sağlıklı çalışmaz. Bunu engellemenin en basit yolu task tanımlanırken continuationOption parametresine TaskContinationOptions enumından ihtiyacımız olan değeri atamaktır.

Yukarıdaki örnekte eğer rastgele oluşturulan sayı tek ise çıktı aşağıdaki gibi olacaktır;

Task 1 running.
Task 1 completed, result is: Task 1 result
task1 status: RanToCompletion
successHandler status: RanToCompletion
failHandle status: Canceled

Eğer sayı çift ise;

Task 1 running.
Task 1 failed. Status: Faulted
task1 status: Faulted
successHandler status: Canceled
failHandle status: RanToCompletion

Barrier

Farklı taskler içerisinde yapılan işlemleri fazlara ayırmak ve bu tasklerdeki yazılan kod satırlarını senkron çalıştırmak amaçlı kullanılır.

Yukarıdaki örnek barrier dikkate alınmadan okunduğunda beklenilen çıktı aşağıdaki gibi olur;

fastTask is doing something… || longRunningTask is doing something…longRunningTask is doing something… || fastTask is doing something…fastTask is done
longRunningTask is done
Done...

Ancak barrier fastTask içerisinde çalıştığında henüz ikinci adım tamamlanmadığı için beklemeye geçecek ve SignalAndWait metodundan sonraki işlemler yapılamayacaktır, ta ki ikinci adım tamamlanana kadar. Bu yüzden terminale longRunningTask is done yazılmadan önce fastRunningTask is done yazılması mümkün değildir.

Çıktı aşağıdaki gibi olacaktır;

fastTask is doing something… || longRunningTask is doing something…longRunningTask is doing something… || fastTask is doing something…
Phase 0 completed.
faskTask is done.
Done...

Barrier ile benzer işlevleri ufak farklılıklar ile sağlayabilen diğer sınıflar.

--

--