Reputation: 85
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
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