0

In my C# project I have to open a bunch of images.

Let's say we need to open 50. My plan is to create 10 Tasks, do some stuff, and then wait for each to complete before the next 10 Tasks are created.

var fd = new OpenFileDialog
{
    Multiselect = true,
    Title = "Open Image",
    Filter = "Image|*.jpg"
};

using (fd)
{
    if (fd.ShowDialog() == DialogResult.OK)
    {
       int i = 1;                
       foreach (String file in fd.FileNames)
       { 
           if (i <= 10) {
               i++;
               Console.WriteLine(i + ";" + file);
               Task task = new Task(() =>
               {
                   // do some stuff
               });
               task.Start();
           } 
           else
           {
               Task.WaitAll();
               i = 1;
           } 
       }  
    }
}
Console.WriteLine("Wait for Tasks");
Task.WaitAll();
Console.WriteLine("Waited);

The Code is not waiting when i=10 and at the end it is also not waiting. Does anyone have an idea how to fix it?

Draken
  • 3,134
  • 13
  • 34
  • 54
Schlodi
  • 149
  • 1
  • 15
  • Just use `Task.ContinueWith` – Software Dev Mar 13 '18 at 18:25
  • `Task.WaitAll();` in a WinForms app == certain death by deadlock. Async properly or not at all. https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – spender Mar 13 '18 at 18:25
  • 3
    `Task.WaitAll` expects a Task collection to wait, you never pass anything in.... – Igor Mar 13 '18 at 18:26
  • As a side note you should check out: [Regarding usage of Task.Start() , Task.Run() and Task.Factory.StartNew()](https://stackoverflow.com/a/29693430/1260204) – Igor Mar 13 '18 at 18:37
  • Thanks! I know the code is crap, but for my plan it is working fine. :) – Schlodi Mar 13 '18 at 18:40

1 Answers1

4

Task.WaitAll expects a Task array to wait, you never pass anything in. The following change will wait all the tasks you start.

List<Task> tasksToWait = new List<Task>();
foreach (String file in fd.FileNames)
{ 
   if (i <= 10) {
       i++;
       Console.WriteLine(i + ";" + file);
       Task task = new Task(() =>
       {
           // do some stuff
       });
       task.Start();
       tasksToWait.Add(task);
   } 
   else
   {
       Task.WaitAll(tasksToWait.ToArray());
       tasksToWait.Clear();
       i = 1;
   } 
} 

This is a code fragment from your code above that has changes


Note This answer does not contain a critique on your choice of design and the possible pitfalls thereof.

Engineert
  • 192
  • 1
  • 1
  • 16
Igor
  • 60,821
  • 10
  • 100
  • 175
  • Thanks Igor! I know my code could be crap, but it is okay for me. Your code helped me a lot. Thanks! – Schlodi Mar 13 '18 at 18:42
  • Task.WaitAll just excepts Array List. Thus, you should call like `Task.WaitAll(tasksToWait.ToArray())` – Engineert Sep 11 '19 at 08:04