2010-12-17 48 views
2

下面的代碼運行正常。我想知道它是否真的正確?C#4.0從Parallel.ForEach內部訪問窗體控件​​

if (openFileDialog.ShowDialog() == DialogResult.OK) 
{ 
    Parallel.ForEach(openFileDialog.FileNames, currentFile => 
    { 
     try 
     { 
      StreamReader FileReader = new StreamReader(currentFile); 
      do 
      { 
       URLtextBox.Invoke(new MethodInvoker(delegate 
       { 
        URLtextBox.Text += SelectURLfromString(FileReader.ReadLine()); 
       })); 
      } 
      while (FileReader.Peek() != -1); 
      FileReader.Close(); 
     } 
     catch (System.Security.SecurityException ex) 
     { 
      ... 
     } 
     catch (Exception ex) 
     { 
      ... 
     } 
    }); 
} 

否則我得到的不是「跨線程操作無效。控制‘URLtextBox’從另一個線程訪問」或卡住的應用。

回答

5

的代碼是正確的 - 你需要使用Invoke從GUI線程之外刷新控制。但是,您excuting在GUI線程SelectURLfromString(FileReader.ReadLine());方法爲好,則應更換通過

string url = SelectURLfromString(FileReader.ReadLine()); 
    URLtextBox.Invoke(new MethodInvoker(delegate 
    { 
     URLtextBox.Text += url; 
    })); 

,以儘量減少在GUI線程最低的工作。

1

Invoke是必要的,因爲控件綁定到創建其關聯的User32窗口的線程(通常稱爲HWND)。也就是說,您可以通過閱讀和處理Invoke委託人以外的文件內容來優化一些內容。

2

代碼是正確的,您需要調用Invoke,以便在GUI線程中更新控件。

然而,也有一些其他的東西,並沒有真正意義的代碼:

  • 你正在做的是使用不平行的資源並行操作。你的線程將爭奪盤面的關注,這顯然是瓶頸,因爲它的速度相對較低。

  • 您將讀取來自多個文件的行,並將它們混合在一個文本框中混合。在這種特定的情況下,這可能是完全正確的,但通常它會帶來不可預測的結果。

  • 您正在使用+=操作來連接字符串,這是一種臭名昭着的方法,因爲它的可擴展性很差。儘管如此,這可能不是一個大問題,因爲磁盤瓶頸可能要差很多。

+0

哦,好評!謝謝。 – 84RR1573R 2010-12-18 00:33:47