2011-04-11 79 views
0

確定之前大家發佈重複讓我告訴你我已經看過所有這些其他職位,我仍然失去了一些說使用委託或後臺工作人員等......但我怎麼會讓這個線程安全我想要在自己的線程上刪除這些文件。跨線程問題與列表查看

這裏是我正在使用的代碼。

private void button1_Click(object sender, EventArgs e) 
{ 
    cleanFiles.RunWorkerAsync(); 
} 

private void cleanFiles_DoWork(object sender, DoWorkEventArgs e) 
{ 
    if (listView1.CheckedItems.Count != 0) 
    { 
     // If so, loop through all checked files and delete. 
     for (int x = 0; x <= listView1.CheckedItems.Count - 1; x++) 
     { 
      string tempDirectory = Path.GetTempPath(); 
      foreach (ListViewItem item in listView1.CheckedItems) 
      { 
       string fileName = item.Text; 
       string filePath = Path.Combine(tempDirectory, fileName); 

       try 
       { 
        File.Delete(filePath); 
       } 
       catch (Exception) 
       { 
        //ignore files being in use 
       } 
      } 
     } 
     PaintListView(tFile); 
     MessageBox.Show("Files removed"); 
     toolStripStatusLabel1.Text = ("Ready"); 
    } 
    else 
    { 
     MessageBox.Show("Please put a check by the files you want to delete"); 
    } 
} 

回答

0

的問題是,你不能(即:cleanFiles_DoWork方法裏面的任何東西)從後臺線程訪問的ListView(listView1)的任何屬性直接。在用戶界面線程以外的任何線程上都無法訪問用戶界面控件。

相反,您應該在調用DoWork之前將項目列表設置爲「乾淨」,然後通過RunWorkerAsync overload taking an object將這些項目傳遞給方法,並通過DoWorkEventArgs.Argument在您的方法中檢索它。

這將允許您傳遞要處理的項目列表,在後臺處理它們,然後在完成時更新列表。

+0

請給我一個例子以上面我的代碼? – partialdata 2011-04-11 20:23:29

+0

你談論製作一個列表,是否有一種方法,當項目被選中時,它會將該文件添加到數組的路徑中?那麼當你打到乾淨的時候,它會將該數組列表發送到乾淨的文件方法,然後啓動一個線程並刪除這些文件? – partialdata 2011-04-11 20:49:46

2

正如裏德所說,你不能從UI線程本身以外的線程訪問UI元素。所以,你必須要在一個委託Control.Invoke()傳遞到與UI線程中執行,這樣

嘗試

private void cleanFiles_DoWork(object sender, DoWorkEventArgs e) 
    { 
     if (listView1.CheckedItems.Count != 0) 
     { 
      // If so, loop through all checked files and delete. 
      for (int x = 0; x <= listView1.CheckedItems.Count - 1; x++) 
      { 
       string tempDirectory = Path.GetTempPath(); 
       foreach (ListViewItem item in listView1.CheckedItems) 
       { 
        string fileName = item.Text; 
        string filePath = Path.Combine(tempDirectory, fileName); 

        try 
        { 
         File.Delete(filePath); 
        } 
        catch (Exception) 
        { 
         //ignore files being in use 
        } 
       } 
      } 

      PaintListViewAndSetLabel(); 
     } 
     else 
     { 
      ShowMessageBox(); 
     } 
    } 

    private void ShowMessageBox() 
    { 
     if(InvokeRequired) 
     { 
      this.Invoke(new Action(ShowMessageBox), new object[0]); 
      return; 
     } 
     MessageBox.Show("Please put a check by the files you want to delete"); 
    } 

    private void PaintListViewAndSetLabel() 
    { 
     if (InvokeRequired) 
     { 
      this.Invoke(new Action(PaintListViewAndSetLabel),new object[0]); 
      return; 
     } 
     PaintListView(tFile); 
     MessageBox.Show("Files removed"); 
     toolStripStatusLabel1.Text = ("Ready"); 
    } 
+0

謝謝你的幫助!我正在處理所有的信息! ;] 大聲笑 ! – partialdata 2011-04-11 19:09:06

+0

我試過上面的代碼相同的問題做它在if(listView1.CheckedItems.Count!= 0)怪胎我需要移出背景工作者,只使用線程嗎? – partialdata 2011-04-11 19:26:57

+0

通常從視圖中獲取某些內容應該沒問題;它只是設置需要調用'Invoke()'的東西 – 2011-04-11 19:29:18

0

它的壞主意,使用從後臺輔助控制,最近我有同樣的問題與TreeView控件。因此,針對Windows窗體控件的線程安全調用解決方案來自Microsoft的How-to article。它使用你的控件的InvokeRequired屬性來檢查安全性的主要思想,並且如果存在的話,通過Invoke方法調用線程安全的方法。