2014-01-20 49 views
1

因此,在下面的片段中,我非常簡單地查看特定文件夾並將圖像從源文件複製到目標文件。進度條凍結部分路徑

副本速度非常快,對於需要幾秒鐘的第一批文件夾(大概20個左右)來說,它的效果非常好。但隨後進度條停止移動,我得到一個旋轉的鼠標光標。我可以查看目標文件夾,它仍在處理文件夾。

當它完成後,我得到「過程完成」對話框,進度條是100%,一切運行良好。

只是想確保最終用戶不認爲它被凍結。

private void readInvoices() 
     { 
      string InvoiceFile = txtInvoiceFile.Text; 
      //read in the text file and get all the invoices to copy 
      string[] Invoices = File.ReadAllLines(InvoiceFile); 
      //set the max val of the progress bar 
      progBar.Maximum = Invoices.Length; 

      try 
      { 
       //for every invoice 
       foreach (string invoice in Invoices) 
       { 

        //Set the source and destination directories 
        string sourceInvFolder = string.Format(@"{0}\{1}", txtSource.Text, invoice); 
        string destInvFolder = string.Format(@"{0}\{1}", txtDest.Text, invoice); 
        DirectoryInfo SourceDI = new DirectoryInfo(sourceInvFolder); 
        DirectoryInfo DestDI = new DirectoryInfo(destInvFolder); 

        //we know we have it in the CSV but does the directory actually exist? 
        //if so then let's process 
        if (Directory.Exists(SourceDI.FullName) == true) 
        { 
         //let's copy of the files 
         CopyAll(SourceDI, DestDI); 
         RenameFolder(sourceInvFolder); 
        } 
        //inc the progress bar 
        progBar.Increment(1); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show("Error" + ex.Message); 
      } 
      finally 
      { 
       MessageBox.Show("Process Complete"); 
       CleanUp(); 
      } 


     } 
+1

我的猜測是你正在UI線程中完成所有這些工作。那肯定會凍結一些東西。儘管目前我們還不能確定,因爲我們無法確定您是如何稱呼您的方法的。一般來說,不要在UI線程中做繁重的工作。 –

回答

0

的UI凍結,因爲它是在一個單獨的線程運行。修復凍結部分的解決方法是將這行代碼放入循環中。

Application.DoEvents(); 

此代碼檢查是否有消息等待處理,如果存在,它會在進入另一個循環之前處理它們。您可以使用ProgressBar控件讓用戶看到已經處理了多少。如果您不想使用單線程方法,請使用BackGroundWorker來防止表單凍結。這是多線程,這意味着一個單獨的線程正在處理某些事情,而您正在做其他事情。

儘管如此,使用上面的代碼會使整個循環過程變得更慢,因爲它必須檢查每個循環,這意味着更多的工作,作爲回報,您會得到實時進度報告。它看起來凍結的原因是循環還沒有完成,你必須先讓它完成,然後才能做其他事情,因爲它在單線程中運行。

+1

請注意,如果您沒有正確使用它,「DoEvents」可能會引起有趣(對我很有趣,而不是您)的副作用。例如,在循環仍在運行時關閉表單不會停止您的程序。無論如何,直到程序退出循環。您可以嘗試查找並防止所​​有這些角落案例,但您將花費相當多的時間來完成這一工作,因爲它是以正確方式學習異步編程的。 –

+0

@Steven Liekens,我完全同意。 DoEvents並不是一切的最佳解決方案。但它確實適用於更簡單的問題。當涉及到大量的工作,多線程是要走的路:) –

+0

因爲這個過程是如此之快,我不介意使用.DoEvents完成它。謝謝! –

1

如果你想Just want to make sure the end user doesn't think it's frozen.你應該使用多線程。此任務的更適合類是BackgroundWorker

從MSDN:

BackgroundWorker的類允許您在一個單獨的,專門的線程運行的操作。諸如下載和數據庫事務等耗時的操作可能會導致您的用戶界面(UI)看起來好像在運行時停止響應一樣。如果您想要一個響應式用戶界面,並且您面臨着與此類操作相關的長時間延遲,則BackgroundWorker類提供了一個便捷的解決方案。

儘量遵循MSDN提供的例子,並把你方法的調用readInvoices()DoWork事件