2016-09-05 1 views
0

BackgroundWorker Cancellationを使用しているときに問題が発生しました。それが終了イベントに行く二度目でBackgroundWorkerが一度だけキャンセルしています

。 backgroundWorker.Dispose()、それをキャンセルした後:

は私が使用する必要がありますか?ここで

は私のコードです:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 

//some logic here before calling the copy method 

//copy folder method 
DirectoryCopy(source, destDirName, true,sender,e); 
} 

private void DirectoryCopy(string sourceDirName, string destDirName, object sender, DoWorkEventArgs e) 
{ 
    // Get the subdirectories for the specified directory. 
    DirectoryInfo dir = new DirectoryInfo(sourceDirName); 

    if (!dir.Exists) 
    { 
     throw new DirectoryNotFoundException(
      "Source directory does not exist or could not be found: " 
      + sourceDirName); 
    } 

    DirectoryInfo[] dirs = dir.GetDirectories(); 
    // If the destination directory doesn't exist, create it. 
    if (!Directory.Exists(destDirName)) 
    { 
     Directory.CreateDirectory(destDirName); 
    } 

    // Get the files in the directory and copy them to the new location. 
    FileInfo[] files = dir.GetFiles(); 

    foreach (FileInfo file in files) 
    { 
     Size += Math.Round(((double)file.Length/1048576), 2); 
     string temppath = System.IO.Path.Combine(destDirName, file.Name); 
     int buflen = 1024; 
     byte[] buf = new byte[buflen]; 
     using (FileStream sourceStream = new FileStream(file.FullName, FileMode.Open)) 
     { 
      using (FileStream destStream = new FileStream(temppath, FileMode.CreateNew)) 
      { 
       while (true) 
       { 
        if ((sender as BackgroundWorker).CancellationPending) 
        { 
         e.Cancel = true; 
         return; 
        } 
        //Progress Logic code 
       } 
      } 
     } 
     i++; 
    } 

    ////If copying subdirectories, copy them and their contents to new location. 
    if (copySubDirs) 
    { 
     // Copy Sub-Directories Logic 
    } 
} 
    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Cancelled) 
    { 
     MessageBox.Show("You cancel the copy!"); 
    } 

    else 
    { 
     MessageBox.Show("All the files were copied!"); 
    } 
    btnCopy.Visibility = Visibility.Visible; 
    btnCancel.Visibility = Visibility.Hidden; 
} 

private void btnCancel_Click(object sender, RoutedEventArgs e) 
{ 
    backgroundWorker1.CancelAsync(); 
} 

はあなたの助けをいただき、ありがとうございます。

答えて

2

BackgroundWorkerが完了したら、それを再起動することはできません。それにDispose()を呼び出すと、になりますが、再起動することはできません。

新しいBackgroundWorkerを作成するか、最新のasyncスタイルのプログラミング(.Net 4.5以降を使用している場合)を使用する必要があります。

+0

ありがとうございます。私は、あなたが言ったように、新しいBackgroundWorkerを作成しました。 – dadou

0

@Matthewワトソンの答えにいくつか修正。

BackgroundWorkerが完了したら、CANを再起動するだけで正しく実行する必要があります。私は何度もやってきたし、いつも働いていた。

(新しいBackgroundWorkersを何度も繰り返し作成することが推奨されますが、使用するリソースを処分する場合は注意してください)複数のワーカーを同時に起動する場合は、スレッドプールの制限、そして、このような複数のスレッドからsimultinouslyドライブ上のファイルに対する操作を実行するように実行する操作は、実際にアプリを遅くすることができる)

同じBackgroundWorkerのを複数回使用して実証する作業コード:

BackgroundWorker bg; 
    .... 
    // Constructor: create the worker (once): 
    bg = new BackgroundWorker(); 
    bg.WorkerSupportsCancellation = true; 
    bg.DoWork += new DoWorkEventHandler(bg_DoWork); 
    bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted); 


    private void btnStartBgw_Click(object sender, EventArgs e) 
    { 
     if (!bg.IsBusy) 
      bg.RunWorkerAsync(); 
     else MessageBox.Show("The worker thread is busy!"); 
    } 

    void bg_DoWork(object sender, DoWorkEventArgs e) 
    { 
     this.DoWorkImpl((BackgroundWorker)sender, e); 
    } 

    private void DoWorkImpl(BackgroundWorker backgroundWorker, DoWorkEventArgs e) 
    { 
     for(int i=0;i<30;i++) 
     { 
      Thread.Sleep(1000); 
      if (backgroundWorker.CancellationPending) 
      { 
       e.Cancel = true; 
       return; 
      } 
     } 
    } 

    void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (e.Cancelled) 
     { 
      MessageBox.Show("The work was canceled"); 
     } 
     else 
     { 
      MessageBox.Show("The work was completed successfuly"); 
     } 
    } 

    private void btnCancelBgw_Click(object sender, EventArgs e) 
    { 
     if (bg.IsBusy) bg.CancelAsync(); 
     else MessageBox.Show("The worker thread is not running!"); 
    } 

また、私はあなたは例外を投げるのを再考すべきだと思うあなたのバックグラウンドスレッド。代わりに、e.Resultにエラーステータスを返すことができます。

0
BackgroundWorker _BackgroundWorker = new BackgroundWorker(); 

    public Form1() 
    { 
     InitializeComponent(); 
     _BackgroundWorker.DoWork += _BackgroundWorker_DoWork; 
     _BackgroundWorker.RunWorkerCompleted += _BackgroundWorker_RunWorkerCompleted; 
     _BackgroundWorker.ProgressChanged += _BackgroundWorker_ProgressChanged; 
     _BackgroundWorker.WorkerSupportsCancellation = true; 
    } 

    void _BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 

    void _BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 

    void _BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 

    private void btnStart_Click(object sender, EventArgs e) 
    { 
     _BackgroundWorker.RunWorkerAsync(e); 
    } 

    private void btnCancel_Click(object sender, EventArgs e) 
    { 
     _BackgroundWorker.CancelAsync(); 
    } 
+0

このコードを使用_BackgroundWorker.WorkerSupportsCancellation = true; –