2017-01-22 1 views
0

私は一度、いくつかのリストを作成ボタンクリックイベントがあり、backgroundworker1開始:doworkイベントでバックグラウンドワーカーがビジーでないことを100%確認してから、それをやり直すにはどうすればよいですか?

private void btnDownload_Click(object sender, EventArgs e) 
     { 
      btnDownload.Enabled = false; 
      label7.Text = "Downloading..."; 
      ei.Init(); 
      if (countryList.Count() == 0) 
      { 
       foreach (ExtractImages.Continent continent in ei.world.continents) 
       { 
        foreach (ExtractImages.Country country in continent.countries) 
        { 
         if (country.name == "Israel") 
         { 
          foreach (string imageUri in country.imageUrls) 
          { 
           countryList.Add(imageUri); 
          } 
         } 
         else 
         { 
          foreach (string imageUri in country.imageUrls) 
          { 
           newList.Add(imageUri); 
          } 
         } 
        } 
       } 
      } 
      backgroundWorker1.RunWorkerAsync(); 
     } 

doworkイベントで
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 

      if (downloaded == false) 
      { 
       getTotalBytes(countryList); 
       CreateCountryDateTimeDirectories(countryList); 
       downloadFile(countryList); 
      } 
      else 
      { 
       getTotalBytes(newList); 
       CreateCountryDateTimeDirectories(newList); 
       downloadFile(newList); 
      } 
     } 

を私は2つの位相を有する第一、それはようになりますリストリストのリンクをダウンロードします。

私がしたいのは、countryLinks内のすべてのリンクをダウンロードしてbackgroundworker1をもう一度開始し、今回はList newListのリンクをダウンロードすることです。

これは、リスト内のリンクをダウンロードする方法です。

private Queue<string> _downloadUrls = new Queue<string>(); 

     private int urlCount = 0; // keep track of how many urls are processed 

     private async void downloadFile(IEnumerable<string> urls) 
     { 
      urlCount = 0; 
      foreach (var url in urls) 
      { 
       _downloadUrls.Enqueue(url); 
       urlCount++; 
      } 
      // urlCount is now set 
      await DownloadFile(); 
     } 

     private async Task DownloadFile() 
     { 
      if (_downloadUrls.Any()) 
      { 
       WebClient client = new WebClient(); 
       client.DownloadProgressChanged += ProgressChanged; 
       client.DownloadFileCompleted += Completed; 

       var url = _downloadUrls.Dequeue(); 

       sw = Stopwatch.StartNew(); 

       if (url.Contains("true")) 
       { 
        await client.DownloadFileTaskAsync(new Uri(url), @"c:\temp\TempSatFiles\" + urlCount + "Infrared.jpg"); 
        //await client.DownloadFileTaskAsync(new Uri(url), countriesMainPath + "\\" + currentDownloadCountry + "\\" + urlCount + "Infrared.jpg"); 
       } 
       else 
       { 
        await client.DownloadFileTaskAsync(new Uri(url), @"c:\temp\TempSatFiles\" + urlCount + "Invisible.jpg"); 
        //await client.DownloadFileTaskAsync(new Uri(url), countriesMainPath + "\\" + currentDownloadCountry + "\\" + urlCount + "Invisible.jpg"); 
       } 

       return; 
      } 
     } 

     double percentageTotalDownload = 0; 
     double totalBytesDownloaded = 0; 
     private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e) 
     { 
      // Calculate download speed and output it to labelSpeed. 
      label3.Text = string.Format("{0} kb/s", (e.BytesReceived/1024d/sw.Elapsed.TotalSeconds).ToString("0.00")); 

      // Update the progressbar percentage only when the value is not the same. 
      double bytesInCurrentDownload = (double)e.BytesReceived; 
      double totalBytesCurrentDownload = double.Parse(e.TotalBytesToReceive.ToString()); 
      double percentageCurrentDownload = bytesInCurrentDownload/totalBytesCurrentDownload * 100; 
      ProgressBar1.Value = int.Parse(Math.Truncate(percentageCurrentDownload).ToString());//e.ProgressPercentage; 
                           // Show the percentage on our label. 
      Label4.Text = e.ProgressPercentage.ToString() + "%"; 

      // Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading 
      label10.Text = string.Format("{0} MB's/{1} MB's", 
       (e.BytesReceived/1024d/1024d).ToString("0.00"), 
       (e.TotalBytesToReceive/1024d/1024d).ToString("0.00")); 

      //Let's update ProgressBar2 
      totalBytesDownloaded = e.BytesReceived + bytesFromCompletedFiles; 
      percentageTotalDownload = totalBytesDownloaded/totalBytesToDownload * 100; 
      progressBar2.Value = (int)percentageTotalDownload; 
      label6.Text = progressBar2.Value.ToString() + "%"; 
     } 

     long bytesFromCompletedFiles = 0; 
     private async void Completed(object sender, AsyncCompletedEventArgs e) 
     { 
      var cnt = System.Threading.Interlocked.Decrement(ref urlCount); 

      if (cnt > 0) 
      { 
       await DownloadFile(); 
       label9.Text = urlCount.ToString(); 
      } 
      else 
      { 
       label7.Text = "Download completed"; 
       downloaded = true; 
       btnDownload.Enabled = true; 
       sw.Stop(); 
      } 
     } 

これで、countryListにリンクがダウンロードされます。 それが他の部分に取得するリスト内のすべてのファイルをダウンロードし終える:

ここ
label7.Text = "Download completed"; 
downloaded = true; 
btnDownload.Enabled = true; 
sw.Stop(); 

私はそれがnewList内のリンクをダウンロードしますdoworkイベントでbackgroundworker1と、この時間を再起動します。

問題は、backgroundworker1がビジーではないことをどのように知っていますか?それは、すべてのファイルをダウンロードし、backgroundworker1はまだ忙しい状況がありますか?

または、私はバックグラウンドワーカーの完了イベントでバックグラウンドワーカーを開始する必要がありますか?それがすべてのダウンロードを完了したら、それはbackgroundworker完了イベントになるでしょうか?最初に完成したwebclientイベントに行きますか?労働者が使用して忙しいかどうかをチェックすることができます

+0

複数の 'BackgroundWorker'を管理することは常に厄介です。これはあなたのコードが[BGWから 'Task.Run'にアップグレードする]準備ができているという兆候の1つです(http://blog.stephencleary.com/2013/05/taskrun-vs-backgroundworker-intro.html)。 –

答えて

1

...それはその後、労働者は、ダウンロードが完了したときに終了します終了すると、あなたが適切にチェックした場合

if(!backgroundworker1 .IsBusy) 
    backgroundworker1 .RunWorkerAsync(); 

ありません、それができますそれが応答を待つときに忙しくて、応答はすぐに来ない。 はい、作業者が作業を完了したら、他の作業を行うために作業を再開することをお勧めします。 はい、終了すると完了したイベントが発生します。 webclientのイベントがbackgroundworkerイベントの内側にある場合、webclient completedイベントが最初に表示されます。最初にコードをデバッグして、コードの流れを確認しなければなりません。

関連する問題