如何确保100%背景工作者不忙,然后重新开始呢?

时间:2017-01-22 16:23:06

标签: c# .net winforms

我有一个按钮点击事件,我在其中创建一些列表并启动backgroundworker1:

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);
            }
        }

在dowork事件中,我首先有两个阶段进行计算,并将下载List countryList中的链接。

我想要做的是一旦完成下载countryLinks start 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中的链接。 当它完成下载List中的所有文件后,它将进入else部分:

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

这里我想重新启动backgroundworker1,这次在dowork事件中它将下载newList中的链接。

问题是如何知道backgroundworker1不忙?可能存在下载所有文件且backgroundworker1仍然忙的情况?

或许我应该在已完成的backgroundworker事件中启动backgroundworker?如果它完成了所有下载,那么它将进入后台工作者完成的事件?或者首先它将进入webclient完成的事件?

1 个答案:

答案 0 :(得分:1)

您可以使用...

检查工作人员是否忙碌
if(!backgroundworker1 .IsBusy)
  backgroundworker1 .RunWorkerAsync();

不,如果您在完成时已经正确检查,那么工作人员将在下载完成时完成,它可能会在等待响应时很忙,并且响应不会很快到来。 是的,当工人完成工作时,建议(从我这边)再次启动它以执行其他任务。 是的,只要它完成,完成的事件将被解雇。 webclient事件在backgroundworker事件中,webclient完成事件将是第一个。您首先要调试代码以查看代码的顺序流程。