2014-10-17 36 views
1

我有以下代碼,我試圖打開一個目錄並通過後臺工作人員處理其中的文件,但我遇到了問題。在後臺工作人員查詢中打開一個目錄並處理文件/文件夾

我遇到的錯誤是(名稱filePath在當前上下文中不存在),我可以理解它,因爲它存儲在另一個方法中?如果有人可以指出我的代碼有什麼問題,我將不勝感激。 Folderbrowser不能在後臺工作器部分下工作。

private void btnFiles_Click(object sender, EventArgs e) 
    { 
     //btnFiles.Enabled = false; 
     btnSTOP.Enabled = true; 
     //Clear text fields 
     listBoxResults.Items.Clear(); 
     listBoxPath.Items.Clear(); 
     txtItemsFound.Text = String.Empty; 
     //Open folder browser for user to select the folder to scan 
     DialogResult result = folderBrowserDialog1.ShowDialog(); 
     if (result == DialogResult.OK) 
     { 
      //Store selected folder path 
      string filePath = folderBrowserDialog1.SelectedPath; 
     } 
     //Start the async operation here 
     backgroundWorker1.RunWorkerAsync(); 
    } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     //Process the folder 
      try 
      { 
       foreach (string dir in Alphaleonis.Win32.Filesystem.Directory.EnumerateFiles(filePath, "*.*", SearchOption.AllDirectories, true)) 
       { 
        //Populate List Box with all files found 
        this.Invoke(new Action(() => listUpdate2(dir))); 
        FileInfo fi = new FileInfo(dir); 
        if (fi.Length == 0) 
        { 
         //Populate List Box with all empty files found 
         this.Invoke(new Action(() => listUpdate1(dir + Environment.NewLine))); 
        } 
       } 
      } 

      //Catch exceptions 
      catch (Exception err) 
      { 
       // This code just writes out the message and continues to recurse. 
       log.Add(err.Message); 
       //throw; 
      } 
      finally 
      { 
       //add a count of the empty files here 
       txtItemsFound.Text = listBoxResults.Items.Count.ToString(); 

       // Write out all the files that could not be processed. 
       foreach (string s in log) 
       { 
        this.Invoke(new Action(() => listUpdate1(s))); 
       } 
       log.Clear(); 
       MessageBox.Show("Scanning Complete", "Done", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
      } 
      //If cancel button was pressed while the execution is in progress 
      //Change the state from cancellation ---> cancelled 
      if (backgroundWorker1.CancellationPending) 
      { 
       e.Cancel = true; 
       //backgroundWorker1.ReportProgress(0); 
       return; 
      } 
      //} 
      //Report 100% completion on operation completed 
      backgroundWorker1.ReportProgress(100); 
     } 

回答

1

將變量「filePath」聲明爲btnFiles_Click方法的本地變量。爲了讓它在別處使用,它必須聲明爲全局的代碼頁:

public class Form1 
{ 
    private String _filePath = null; 

    private void btnFiles_Click(object sender, EventArgs e) 
    { 
     //get your file and assign _filePath here... 
     _filePath = folderBrowserDialog1.SelectedPath; 
    } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     //use _filePath here... 
    } 
} 
+0

謝謝唐,就這樣。 – Exception 2014-10-17 12:32:00

+1

請注意,只要BackgroundWorker線程知道,理論上可以讓_filePath變量保持未初始化狀態。如果你想在線程之間共享變量,它們應該用一種同步的形式(例如鎖定語句)來保護,或者應該被聲明爲「volatile」。即使在x86上(數據訪問始終是易失性語義),您也不希望某些編譯器優化讓您苦惱,並且.NET在其他平臺(例如ARM)上運行取決於特定於平臺的行爲是一個壞主意。 – 2014-10-17 18:14:11

3

@DonBoitnott解決方案是最常見的用於內部類的數據流。具體到BackgroundWorker還有另一個存在

private void btnFiles_Click(object sender, EventArgs e) 
{ 
    ... 
    // pass folder name 
    backgroundWorker1.RunWorkerAsync(folderBrowserDialog1.SelectedPath); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // get passed folder name 
    string filePath = (string)e.Argument; 
    ... 
} 
+0

謝謝你的例子Sinatr – Exception 2014-10-17 12:32:39

+0

恕我直言,這實際上是更好的解決方案,因爲它避免了跨線程同步問題的方式(請參閱我在其他答案中的評論)。至少在傳遞值類型和不可變引用類型對象(如字符串)時,完全避免了跨線程同步問題。 – 2014-10-17 18:22:23

相關問題