2016-04-21 99 views
2

這是我第一次在C#中使用進度條。 我的代碼正在複製一些文件,我想通過進度條顯示進度。正確使用進度條

我不喜歡我的代碼的事情是,我必須通過所有文件來設置最大的酒吧......後來我再次通過相同的過程複製文件。

我只是想不出一種方法來確保酒吧的流暢進步而不會做到這一點。我首先必須知道最大的權利?或者有一個竅門?

代碼看起來像這樣:

  • 設置最大:

    private static void setProgressBar(List<Source> sources, List<Destination> destinations) 
    { 
        progress.Value = 0; 
        progress.Maximum = 0; 
    
        foreach (var source in sources) 
        { 
         progress.Maximum += System.IO.Directory.GetDirectories(source.directory, "*", 
          SearchOption.AllDirectories).Count() * destinations.Count + 
          System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories).Count() * 
          destinations.Count; 
        } 
    
  • 複製文件:

    public static void CopyData(List<Source> sources, List<Destination> destinations, RichTextBox box, ProgressBar bar) 
    { 
        log = box; 
        progress = bar; 
        setProgressBar(sources, destinations); 
    
        foreach (var source in sources) 
        { 
         foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", 
          SearchOption.AllDirectories)) 
         { 
          foreach (var destination in destinations) 
          { 
           logger(dirPath); 
           System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory)); 
          } 
         } 
    
         foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories)) 
         { 
          foreach (var destination in destinations) 
          { 
           logger(newPath); 
           File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true); 
          } 
         } 
        } 
    } 
    
  • 增量進度條:

    private static void logger(string output) log.Text + =「Copy:」+ output + System.Environment.NewLine; log.SelectionStart = log.Text.Length; log.ScrollToCaret(); progress.Increment(1); }

於是我運行相同的代碼兩次......,我不喜歡這樣:)

回答

1

我看到兩個錯誤在這裏:你永遠在了CopyData設置你的進度的值方法 和第二個是:您的CopyData方法將導致您的用戶界面凍結,直到方法完成(並且進度條此時從0跳到100%)。

您可以將您的CopyData方法放入BackgroundWorker中,並調用ReportProgress並在ReportProgress事件中設置您的酒吧的新值。

下面是它如何完成的一個例子。相反static void Main(..)呼叫從那裏您將開始您的了CopyData法

static void Main(string[] args) 
{ 
    System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker(); 
    worker.ProgressChanged += Worker_ProgressChanged; 
    worker.DoWork += Worker_DoWork; 

    //Do work 
    worker.RunWorkerAsync(); 
} 

private static void Worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
{ 
    //Get Values 
    var source = null; 
    var destinations = null; 

    //CopyData Method 
    setProgressBar(sources, destinations); 
    foreach (var source in sources) 
    { 
     foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories)) 
     { 
      foreach (var destination in destinations) 
      { 
       logger(dirPath); 
       System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory)); 
       //Increase Value by 1 
       (sender as System.ComponentModel.BackgroundWorker).ReportProgress(1); 
      } 
     } 

     foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories)) 
     { 
      foreach (var destination in destinations) 
      { 
       logger(newPath); 
       File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true); 
       //Increase Value by 1 
       (sender as System.ComponentModel.BackgroundWorker).ReportProgress(1); 
      } 
     } 
    } 
} 

private static void Worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) 
{ 
    if (e.ProgressPercentage == 1) 
    { 
     //If Value gets higher than Maximum it will cause an Exception 
     if (progress.Value < progress.Maximum) 
      progress.Value += 1; 
    } 
} 

private static void setProgressBar(List sources, List destinations) 
{ 
    progress.Value = 0; 
    progress.Maximum = 0; 
    foreach (var source in sources) 
    { 
     foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories)) 
     { 
      //Simplified 
      progress.Maximum += destinations.Count; 
     } 

     foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories)) 
     { 
      //Simplified 
      progress.Maximum += destinations.Count; 
     } 
    } 
} 
+0

感謝您的答覆的工人, 首先是一個方法缺失,所以你不能看到,我做遞增進度條的值'記錄器(newPath)'方法。 因此它不會從0跳到100. 其次,通過BackgroundWorker執行此操作不會改善性能密集程度最高的代碼(您簡化的代碼)運行兩次的情況!想象一下,有2000個目錄程序會減慢1.5。 - 2次。我正在尋找一種方法來改善這一點。不知道是否有可能 –

+1

我讀了一些關於後臺工作者的文章,我看到他們在不同的線程中運行。 所以我認爲你的答案幫助我! –

+0

很高興聽到關於性能密集型代碼的其他問題:)。您可以忽略直到您寫入文件的位置的目錄,並檢查目標文件的目錄是否存在。如果沒有 - >創建它。這是迄今爲止關於這部分問題的唯一想法。 –