2011-11-19 61 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); 
}