2016-11-01 9 views
-1

ユーザーがUIから選択するドライブにディレクトリから(再帰的に)いくつかのファイルをコピーしているWindowsアプリケーション(C#)があります。各ボタンは、バックグラウンドワーカーがファイルをコピーするために実行する時間を犠牲にします。

素晴らしい作品です。すべてのファイルが適切なドライブに移動します。

ただし、ボタンがクリックされた回数に応じてプロセスが増加します。

I.E.

  • ユーザーがクリックする「バックアップのデスクトップ」とそれが
  • 次に、ユーザが「バックアップのお気に入り」をクリックすると、それは二回、100%完了するまで実行さ100%完了するまで実行されます。
  • ユーザーは他のボタンをクリックすると、100%完了まで3回実行されます。

私の次のコードでは、プロセスが完了した回数を増やすためにどこに呼び出されているのかわかりません。

私はどこかでそれを見逃していると確信しています - 私はちょうどどこを知りません。

私はプログレスバーを使用しているため、ユーザーにグラフィックを教えてもらうことができます。意図したとおりに動作します。

/* 
* ***** * 
* Copy all directories and files recursively 
* ***** * 
*/ 
public void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) 
{ 
    foreach (DirectoryInfo dir in source.GetDirectories()) 
    { 
     if ((dir.Name == "My Music") || (dir.Name == "My Pictures") || (dir.Name == "My Videos")) 
     { 
      //do nothing with it since it is just a system link we cannot access 
     } 
     else 
     { 
      CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name)); 
     } 
    } 
    foreach (FileInfo file in source.GetFiles()) 
     file.CopyTo(Path.Combine(target.FullName, file.Name), true); 
} 

/* 
* ***** 
* PROGRESS BAR METHODS * 
* ***** 
*/ 
void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    string buttonSender = clickedButton; //Desktop, Documents, etc. 
    switch (buttonSender) { 
     case "Desktop": 
      destinationLocation = selectedDrive + "Backups-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year.ToString() + "\\Desktop\\"; 
      string desktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); 
      source = new DirectoryInfo(desktopFolder); 
      break; 
     case "Documents": 
      destinationLocation = selectedDrive + "Backups-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year.ToString() + "\\Documents\\"; 
      string documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
      source = new DirectoryInfo(documentsFolder); 
      break; 
     case "Favorites": 
      destinationLocation = selectedDrive + "Backups-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year.ToString() + "\\Favorites\\"; 
      string favoritesFolder = Environment.GetFolderPath(Environment.SpecialFolder.Favorites); 
      source = new DirectoryInfo(favoritesFolder); 
      break; 
     default : 

      break; 
    } 

    DirectoryInfo target = new DirectoryInfo(destinationLocation); 
    fileCount = source.GetFiles("*", SearchOption.AllDirectories).Length; 
    totalFileCount = fileCount; 
    int total = totalFileCount; //some number (this is your variable to change)!! 
    for (int i = 0; i <= total; i++) //some number (total) 
    { 
     System.Threading.Thread.Sleep(100); 
     int percents = (i * 100)/total; 
     bgWorker.ReportProgress(percents, i); 
     //2 arguments: 
     //1. procenteges (from 0 t0 100) - i do a calcumation 
     //2. some current value! 
    } 
    if (!Directory.Exists(destinationLocation)) 
    { 
     Directory.CreateDirectory(destinationLocation); 
    } 
    CopyFilesRecursively(source, target); 
} 

void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    essentialItemsProgressBar.Visible = true; 
    essentialItemsProgressBar.Value = e.ProgressPercentage; 

    int percent = (int)(((double)(essentialItemsProgressBar.Value - essentialItemsProgressBar.Minimum)/
    (double)(essentialItemsProgressBar.Maximum - essentialItemsProgressBar.Minimum)) * 100); 
    using (Graphics gr = essentialItemsProgressBar.CreateGraphics()) 
    { 
     gr.DrawString(percent.ToString() + "%", 
      SystemFonts.DefaultFont, 
      Brushes.Black, 
      new PointF(essentialItemsProgressBar.Width/2 - (gr.MeasureString(percent.ToString() + "%", 
       SystemFonts.DefaultFont).Width/2.0F), 
      essentialItemsProgressBar.Height/2 - (gr.MeasureString(percent.ToString() + "%", 
       SystemFonts.DefaultFont).Height/2.0F))); 
    } 

    essentialItemsProgressLabel.Visible = true; 
    essentialItemsProgressLabel.Text = String.Format("Progress: {0} % - All {1} Files Transferred", e.ProgressPercentage, clickedButton); 
    //essentialItemsProgressLabel.Text = String.Format("Total items transfered: {0}", e.UserState); 
} 

void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    //do the code when bgv completes its work 
    essentialItemsProgressBar.Visible = false; 
} 
/* 
* ***** 
* END OF PROGRESS BAR METHODS * 
* ***** 
*/ 
/* 
* ***** DESKTOP BACKUP ***** * 
*/ 
private void backupDesktopButton_Click(object sender, EventArgs e) 
{ 
    clickedButton = ((Button)sender).Text.ToString(); 
    selectedDrive = backupDriveCombo.SelectedItem.ToString(); 
    bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
    bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 
    bgWorker.WorkerReportsProgress = true; 
    bgWorker.RunWorkerAsync(); 
} 
/* 
* ***** DOCUMENTS BACKUP ***** * 
*/ 
private void backupDocumentsButton_Click(object sender, EventArgs e) 
{ 
    clickedButton = ((Button)sender).Text.ToString(); 
    selectedDrive = backupDriveCombo.SelectedItem.ToString(); 
    bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
    bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 
    bgWorker.WorkerReportsProgress = true; 
    bgWorker.RunWorkerAsync(); 
} 
+0

..あなたは**クリックするたびに** DoWorkに**イベントハンドラを追加していますか? – stuartd

+0

どうすればよろしいでしょうか? – Hanny

+0

_ "どうしたらいいの?" 'BackgroundWorker'を一度(フォームにコンポーネントとして追加する場合、デザイナのプロパティウィンドウを使用して設定することもできます)、または実行するたびに新しい' BackgroundWorker'を作成します。しかし、あなたが何をしても、ワーカーを実行するたびに同じオブジェクトの同じイベントに新しいハンドラーを追加し続けるだけではありません。 –

答えて

2

問題は(backupDocumentsButton_Click()方法で)この行である:

bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 

あなたは一度だけ(bgWorkerの作成にすなわち)この操作を行う必要がありますが、あなたは、すべてのボタンのクリックでこれを行います。第一、第二、あなたが1以上の追加]をクリックした後で、ボタンに1つのハンドラを追加]をクリックした後 - それは呼ばれる2回...

あなたはあなたのコードを変更する必要があります。

private void backupDocumentsButton_Click(object sender, EventArgs e) 
{ 
    clickedButton = ((Button)sender).Text.ToString(); 
    selectedDrive = backupDriveCombo.SelectedItem.ToString(); 
    // without these lines 
    // bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
    // bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
    // bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 
    bgWorker.WorkerReportsProgress = true; 
    bgWorker.RunWorkerAsync(); 
} 

そして、あなたは行を追加する必要がありますすなわち、bgWorker作成した後:

BackgroundWorker bgWorker = new BackgroundWorker(); 
bgWorker.DoWork += bgWorker_DoWork; 
bgWorker.ProgressChanged += bgWorker_ProgressChanged; 
bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted; 

あなただけのイベントハンドラを一度に追加する必要があります。

+0

彼らはコメントで同じことを言った - しかし、これは私が容易に見ることができる方法で完全に明らかにした/わかる。ありがとうございました! これはうまくいった。私ができる時に私は数分で受け入れるだろう。 – Hanny

関連する問題