jack rasha
jack rasha

Reputation: 85

Parallel.ForEach in c#4

Why this code does not work ? Please show me the correct way.

 private void BtnStartClick(object sender, EventArgs e)
    {
        var files = Directory.GetFiles(@"D:\pic", "*.png");
        const string newDir = @"D:\pic\NewDir";
        Directory.CreateDirectory(newDir);
        Parallel.ForEach(files, currentFile =>
                                    {
                                        string filename = Path.GetFileName(currentFile);
                                        var bitmap = new Bitmap(currentFile);
                                        bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                                        if (filename == null) return;
                                        bitmap.Save(Path.Combine(newDir, filename));
                                        AddItemToListBox(string.Format("Processing {0} ", filename));
                                    }
            );
    }

    private void AddItemToListBox(string item)
    {
        if (listBox1.InvokeRequired)
        {
            listBox1.Invoke(new StringDelegate(AddItemToListBox), item);
        }
        else
        {
            listBox1.Items.Add(item);
        }
    }

Upvotes: 0

Views: 1104

Answers (1)

Vitaliy
Vitaliy

Reputation: 2804

It looks like the problem with Invoke. Try solution from Problem with Invoke to parallelize foreach

To to avoid blocking UI thread you need to wrap Parallel.ForEach to Task:

private TaskScheduler ui;

private void BtnStartClick(object sender, EventArgs e)
{
    ui = TaskScheduler.FromCurrentSynchronizationContext();

    Task.Factory.StartNew(pforeach)
      .ContinueWith(task =>
      {
          task.Wait(); // Ensure errors are propogated to the UI thread.
      }, ui);
}

private void ForEachFunction()
{
    var files = Directory.GetFiles(@"D:\pic", "*.png");
    const string newDir = @"D:\pic\NewDir";
    Directory.CreateDirectory(newDir);
    Parallel.ForEach(files, 
        currentFile =>
        {     
             string filename = Path.GetFileName(currentFile);
             var bitmap = new Bitmap(currentFile);

             bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
             if (filename == null) return;

             bitmap.Save(Path.Combine(newDir, filename));

             Task.Factory.StartNew(
                 () => AddItemToListBox(string.Format("Processing {0} ", filename)),
                 CancellationToken.None,
                 TaskCreationOptions.None,
                 ui).Wait();
        });
}

private void AddItemToListBox(string item)
{
    listBox1.Items.Add(item);
}

Upvotes: 2

Related Questions