12 Ocak 2018 Cuma

Task Sınıfı

Giriş
Bu sınıfları kullanmak için şu satırı dahil ederiz. Bu sınıf .Net 4.0 ile geldi. Daha önceki sürümlerde Thread ile çalışmaktan başka çare yok.
using System.Threading.Tasks;
Açıklaması şöyle
The Task Parallel Library (TPL) was introduced in .NET 4.0 as a significant improvement in running and managing threads compared to the existing System.Threading the library earlier; this was the big news in its debut.

In short, the Task Parallel Library (TPL) provides more efficient ways to generate and run threads than the traditional Thread class. Behind the scenes, Tasks objects are queued to a thread pool. This thread pool is enhanced with algorithms that determine and adjust the number of threads to run and provide load balancing to maximize throughput. These features make the Tasks relatively lightweight and handle effectively threads than before.

The TPL syntax is more friendly and richer than the Thread library; for example, defining fine-grained parallelism is much easier than before. Among its new features, you can find partitioning of the work, taking care of state management, scheduling threads on the thread pool, using callback methods, and enabling continuation or cancellation of tasks.

The main class in the TPL library is Task; it is a higher-level abstraction of the traditional Thread class. The Task class provides more efficient and more straightforward ways to write and interact with threads. The Task implementation offers fertile ground for handling threads.
Önemli Kavramlar
Task'ı kullanabilmek için şu kavramları bilmek gerekiyor
1. Tasks continuation
2. Paralleling tasks
3. Canceling tasks
4. Synchronizing tasks
5. Converging tasks back to the calling thread
İkinci madde için Parallel.Invoke(), Parallel.ForEach() ve Parallel.For() kullanılır
Dördüncü madde için TaskCompletionSource kullanılır
Beşinci madde için Task.Wait(), Task.WaitAll(), Task.WhenAny() ve Task.WhenAll() kullanılır

Constructor - Action
Açıklaması şöyle. Bu constructor Task'ı başlatmaz. Hemen başlatmak için Task.Start() veya Task.Factory.StartNew() veya Task.Run() metodlarından birisini kullanmamız gerekir.
The basic constructor of a Task object instantiation is the delegate Action, which returns void and accepts no parameters.
Örnek
Şöyle yaparız.
var task = new Task<Data>(() => ...);
Constructor - Action<Object> + Object
Sadece Action alan constructor'a göre çok da bir fayda sağlamıyor.

AsAsync metodu 
Şöyle yaparız.
public IAsyncAction FindPerson(string personId)
{
  Task t = new Task(() =>
  {
    //Search the person and write to screen 
  });
  t.Start();
  return t.AsAsyncAction();
}
CompletedTask Alanı
Örnek ver

ConfigureAwait metodu 
async metodlarda await'ten sonra gelen kodun hangi thread tarafından çağrılacağını ayarlar. Aşağıdaki kod UI dışından bir yerde çalıştığı için ConfigureAwait(false) yapılıyor. Böylece TestTask()'ı çağıran thread return "TestTask" kısmını çalıştırıyor.
async Task<string> TestTask()
{
    await Task.Delay(2000).ConfigureAwait(false);

    return "TestTask";
}
ContinueWith metodu
Task Sınıfı Continuation yazısına taşıdım

Delay metodu 
Task.Delay ile Thread.Sleep hemen hemen aynı işi yapar. Yani thread'i bir müddet uyutur. Aslında Task.Delay altta System.Threading.Timer sınıfını kullanıyor. Açıklaması şöyle
// on line 5893
// ... and create our timer and make sure that it stays rooted.
if (millisecondsDelay != Timeout.Infinite)
{
  promise.Timer = new Timer(...);
  promise.Timer.KeepRootedWhileScheduled();
}
Thread.Sleep()'ten farklı olarak Task.Delay süre bitmeden iptal edilebilir. Task.Delay .Net 4.5 ile geliyor. Daha önceki ortamlarda aşağıdakine benzer bir kod kullanılabilir.
public static Task Delay(double milliseconds)
{
    var tcs = new TaskCompletionSource<bool>();
    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Elapsed+=(obj, args) =>
    {
        tcs.TrySetResult(true);
    };
    timer.Interval = milliseconds;
    timer.AutoReset = false;
    timer.Start();
    return tcs.Task;
}
Çok hızlı dönen döngülerde özellikle GUI güncellemesi yapılıyorsa bir süre beklemek GUI'nin tıkanmasını engeller.
while (true)
{
  var updateFrequency = Task.Delay(1000);
  if (bStreaming == true)
  {
     textboxTX.Invoke(new Action(() => textboxTX.Text = ...));
     textboxTY.Invoke(new Action(() => textboxTY.Text = ...));
     textboxTZ.Invoke(new Action(() => textboxTZ.Text = ...));
    }
    await updateFrequency;
}
Task.Delay eğer verilen süre 0 ise çalışmaz. Aşağıdaki örnekte callback() metodunu çağırmadan önce verilen süre kadar bekler. Eğer süre 0 ise Yield kullanmak gerekir.
async void setTimeout(dynamic callback, int timeout)
{
    if(timeout > 0)
    {
        await Task.Delay(timeout);
    }
    else
    { 
        await Task.Yield();
    }

    callback();
}
FromResult metodu
Açıklaması şöyle
Creates a Task that's completed successfully with the specified result.
Şöyle yaparız.
Task t = Task.FromResult<bool>(true);
Şu kod ile aynı kapıya çıkar.
Task.Run(() => true);
IsCompleted Alanı
Task'ın bitip bitmediğini belirtir. Örnekte Task bitmediyse, örneğin exception aldıysa IsCompleted false döndüğü için default bir değer döndürülür.
public Task<List<string>> LoadExample()
{
  Task<List<string>> task = LoadMyExampleTask();
  return task.ContinueWith(t => t.IsCompleted ? t.Result : default(List<string>));
}
Run metodu 
Task.Run metodu yazısına taşıdım.

Wait metodu

WaitAll metodu 
Task Sınıfı Converging Back to The Calling Thread yazısına taşıdım

WhenAny metodu

WhenAll metodu

1 yorum:

  1. emeğinize sağlık ancak anlatım çok kötü , hiç bir şey anlamadım. Anlatımınız task ın ne olduğunu ne için kullanıldığına ışık tutmuyor.

    YanıtlaSil