7 Ağustos 2017 Pazartesi

Task.WaitAll metodu

Giriş
Başlatılan Task'ların (bir veya birden fazla) bitmesini beklemek isteyebiliriz. Bu durumda WaitAll kullanılabilir. WaitAll() Task'ların döndürdüğü sonuç ile ilgilenmez. Sadece bitmelerini bekler dolayısıyla void döner.

Bu metod yerine Parallel.ForEach kullanmak çok daha kolay olabilir. Şöyle yaparız.
List<int> ids = new List<int>();

Parallel.ForEach (ids, (id, state, index) => {
  ...
});
WaitAll Parametre Olarak Array Alır
Şöyle yaparız.
List<Task> tasks = new List<Task>();
...
Task.WaitAll(tasks.ToArray());

2 Tane Paralel İşlem Başlat ve Bitmelerini Bekle
Şöyle yaparız.
Task[] tasks = new Task[2];   
tasks[0] = Task.Factory.StartNew (() => YourFunction());
tasks[1] = Task.Factory.StartNew (() => YourFunction());
Task.WaitAll(tasks);// here it will wait untill all the functions get completed
N Tane Paralel İşlem Başlat ve Bitmelerini Bekle
Şöyle yaparız. Önce taskları başlatırız. Daha sonra WaitAll() ile hepsinin bitmesini bekleriz.
Task[] tasks = new Task[partitionCount];

for (int p = 0; p < partitionCount; p++)
{
  tasks[p] = Task.Run(() =>
  {...});
}

Task.WaitAll (tasks);
Throttle Yapmak İçin
Eğer onar onar çalıştırmak istersek şöyle yaparız.
string url = "http://www.xxxx.pl/xxxx/?action=xxxx&id=";

int numberOfConcurrentDownloads = 10;

for (int i = 0; i < 2500; i += numberOfConcurrentDownloads)
{
  List<Task> allDownloads = new List<Task>();
  for (int j = i; j < i + numberOfConcurrentDownloads; j++)
  {
    string tmp = url;
    tmp += Convert.ToString(i);
    allDownloads.Add(checkAvaible(tmp));
  }
  Task.WaitAll(allDownloads.ToArray());
}
İndirme kodu ise async ile yazılı.
async Task checkAvaible(string url)
{
  using (WebClient client = new WebClient())
  {
    string htmlCode = await client.DownloadStringTaskAsync(new Uri(url));
    ...
  }
}
İşlem Sonucu
WaitAll() bittikten sonra sonuçlara Task.Result ile erişiriz. İşte bu noktada aslında WhenAll() metodunun daha iyi olduğunu görebiliriz. Açıklaması şöyle
The main difference between Task.WaitAll and Task.WhenAll is that the former will block (similar to using Wait on a single task) while the latter will not and can be awaited, yielding control back to the caller until all tasks finish.
Şöyle yaparız
Task<object>[] taskList = {
    Task.Factory.StartNew(() => ...),
    Task.Factory.StartNew(() => ...),
    Task.Factory.StartNew(() => ...),
    Task.Factory.StartNew(() => ...)
};

Task.WaitAll(taskList);

ArrayList allObjectAttributes = new ArrayList();

foreach (Task<object> task in taskList) {
    allObjectAttributes.Add(task.Result);
}

return allObjectAttributes;

Hiç yorum yok:

Yorum Gönder