2011-11-19 109 views
0

为什么这段代码不起作用? 请让我看看正确的方法。Parallel.ForEach in c#4

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); 
     } 
    } 
+1

什么是它应该做的?你期望的行为是什么? – Polynomial

+0

它看起来像Invoke的问题。 尝试从[调用问题并行化foreach]解决方案(http://stackoverflow.com/questions/3467816/problem-with-invoke-to-parallelize-foreach) – Vitaliy

回答

2

它看起来像Invoke的问题。尝试从Problem with Invoke to parallelize foreach

解决方案为了避免堵塞你需要用Parallel.ForEach到任务UI线程:

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); 
}