繁体   English   中英

我需要在backgroundworker progresschanged事件中使用invoke吗?

[英]Do I need to use invoke in backgroundworker progresschanged event?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Xml.Linq;
using System.Diagnostics;
using System.Management;
using System.Runtime.InteropServices;

namespace DownloadFiles
{
    public partial class Form1 : Form
    {
        Stopwatch sw = new Stopwatch();
        Stopwatch stopwatch = new Stopwatch();
        string filesdirectory = "Downloaded_Files";
        string mainurl = "http://www.usgodae.org/ftp/outgoing/fnmoc/models/navgem_0.5/latest_data/";
        List<string> parsedlinks = new List<string>();
        string path_exe = Path.GetDirectoryName(Application.LocalUserAppDataPath);

        List<string> results = new List<string>();
        //StreamWriter w = new StreamWriter(@"e:\monitordetector.txt");

        public Form1()
        {
            InitializeComponent();

            //DetectScreenName();

            label3.Text = "";
            label4.Text = "";
            label5.Text = "";
            label7.Text = "";
            button2.Enabled = false;
            button3.Enabled = false;
            filesdirectory = Path.Combine(path_exe, filesdirectory);
            if (!Directory.Exists(filesdirectory))
            {
                Directory.CreateDirectory(filesdirectory);
            }
            else
            {
                if (IsDirectoryEmpty(filesdirectory) == false)
                {
                    button3.Enabled = true;
                }
            }
        }

        public bool IsDirectoryEmpty(string path)
        {
            return !Directory.EnumerateFileSystemEntries(path).Any();
        }

        private string downloadhtml(string url)
        {
            backgroundWorker1.ReportProgress(0, "Downloading Main Url");
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Proxy = null;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream());
            string html = sr.ReadToEnd();
            sr.Close();
            response.Close();
            StreamWriter w = new StreamWriter(path_exe + "\\page.html");
            w.Write(html);
            w.Close();
            return html;
        }

        int Counter = 0;
        int percentage = 0;
        int total = 0;
        int countfiletodownload = 0;
        bool processStatus = false;
        private void Parseanddownloadfiles()
        {
            downloadhtml(mainurl);
            if (bgw.CancellationPending == false)
            {
                backgroundWorker1.ReportProgress(0, "Parsing Links");
                HtmlAgilityPack.HtmlWeb hw = new HtmlAgilityPack.HtmlWeb();
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc = hw.Load(path_exe + "\\page.html");
                foreach (HtmlAgilityPack.HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
                {
                    string hrefValue = link.GetAttributeValue("href", string.Empty);
                    if (hrefValue.Contains("US"))
                    {
                        string url = "http://www.usgodae.org/ftp/outgoing/fnmoc/models/navgem_0.5/latest_data/" + hrefValue;
                        parsedlinks.Add(url);
                        if (bgw.CancellationPending == true)
                            return;
                    }
                }
                countfiletodownload = parsedlinks.Count;
                total = parsedlinks.Count;
                backgroundWorker1.ReportProgress(0, "Downloading Files");
                processStatus = true;
                for (int i = 0; i < parsedlinks.Count && bgw.CancellationPending == false; i++)
                {
                    try
                    {
                        using (WebClient client = new WebClient())
                        {
                            sw.Start();
                            Uri uri = new Uri(parsedlinks[i]);
                            string filename = parsedlinks[i].Substring(71);
                            //client.DownloadFile(parsedlinks[i], filesdirectory + "\\" + filename);
                            client.DownloadFileAsync(uri, filesdirectory + "\\" + filename);
                            Counter += 1;
                            percentage = Counter * 100 / total;
                            string filenametoreport = filename.Substring(1);
                            countfiletodownload--;
                            backgroundWorker1.ReportProgress(percentage, filenametoreport);//countfiletodownload, filenametoreport);
                        }
                    }
                    catch (Exception err)
                    {
                        string error = err.ToString();
                    }
                }
            }
        }

        /*void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            // Calculate download speed and output it to labelSpeed.
            if (label12.InvokeRequired)
            {
                label12.Invoke(new MethodInvoker(delegate
                {
                    label12.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.
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new MethodInvoker(delegate
                {
                    progressBar1.Value = e.ProgressPercentage;
                }));
            }

            // Show the percentage on our label.
            if (label13.InvokeRequired)
            {
                label13.Invoke(new MethodInvoker(delegate
                {
                    label13.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
            if (label14.InvokeRequired)
            {
                label14.Invoke(new MethodInvoker(delegate
                {
                    label14.Text = string.Format("{0} MB's / {1} MB's",
                        (e.BytesReceived / 1024d / 1024d).ToString("0.00"),
                        (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
                }));
            }
        }*/

        /*void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            // Reset the stopwatch.
            sw.Reset();

            if (e.Cancelled == true)
            {
                MessageBox.Show("Download has been canceled.");
            }
            else
            {
                //MessageBox.Show("Download completed!");
            }
        }*/

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        BackgroundWorker bgw;
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            bgw = (BackgroundWorker)sender;
            if (bgw.CancellationPending == true)
            {
                return;
            }
            else
            {
                Parseanddownloadfiles();
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.UserState.ToString() == "Downloading Main Url")
            {
                label3.Text = e.UserState.ToString();
            }
            if (e.UserState.ToString() == "Parsing Links")
            {
                label3.Text = e.UserState.ToString();
            }
            if (e.UserState.ToString() == "Downloading Files")
            {
                label7.Text = countfiletodownload.ToString();//parsedlinks.Count.ToString();
                label3.Text = e.UserState.ToString();
            }
            if (processStatus == true)
            {
                if (e.UserState.ToString() != "Downloading Files")
                {
                    label4.Text = e.UserState.ToString();
                    label7.Text = countfiletodownload.ToString();
                    progressBar1.Value = e.ProgressPercentage;
                    /*using (var bitmap = new Bitmap(this.Width, this.Height))
                    {
                        this.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
                        bitmap.Save(@"e:\screens\ss.gif" + countscreenshots, System.Drawing.Imaging.ImageFormat.Gif);
                        countscreenshots += 1;
                    }*/
                }
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                string fff = null;
            }
            label3.Text = "Operation Cancelled";
            button1.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            label3.Text = "Cancelling Operation";
            backgroundWorker1.CancelAsync();
            button2.Enabled = false;
            timer1.Stop();
            stopwatch.Stop();
            stopwatch.Reset();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            label3.Text = "";
            label4.Text = "";
            label7.Text = "";
            backgroundWorker1.RunWorkerAsync();
            timer1.Start();
            stopwatch.Start();
            button1.Enabled = false;
            button2.Enabled = true;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Process.Start(filesdirectory);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label5.Text = string.Format("{0:hh\\:mm\\:ss}", stopwatch.Elapsed);
        }
    }
}

由于某种原因,事件中的代码使整个应用程序不同步。 如果我注释该代码不使用它,那么它可以正常工作。

我还想使用client_DownloadProgressChanged,它现在不用于显示和显示下载信息。

像使用每次当前文件下载的progressBar信息和整体进度下载的信息那样使用快速时间。

否*,您不需要调用BackgroundWorker的ProgressChanged事件。 DoWork在后台线程上运行,但是在ProgressChanged(以及backgroundworker上的其他事件处理程序)内部执行代码的线程由创建backgroundworker的线程完成,该线程应与创建其他ui控件的线程相同因此不需要发票

*话虽如此,请密切注意我所说的BGW将使用创建BGW的线程运行ProgressChanged事件的部分。 在大多数情况下,这将是UI线程。如果您使用UI线程以外的线程来创建BGW,则单击YES,则需要进行调用。 如果您想简单一点,请在UI线程上与所有其他控件一起创建BGW。 对于我的其余建议,我将假定您已完成此操作。

我无法确切了解您的问题,但请记住,是运行事件处理程序的UI线程。 如果您在执行一些长时任务或阻止操作时将该线程发送出去,以作为更新UI中标签的工作的一部分,那么它将使应用程序看起来已挂起。 您必须让UI线程尽快完成事件处理程序中的代码。 如果它将需要访问来自长时间操作或阻塞操作的数据,请让DoWork在提高其进度之前计算数据,或者使用另一种方法来避免阻塞UI线程,例如异步任务模式

请注意,调用和阻止ui完全不同。 Windows控件只能由创建它们的线程访问。 如果另一个线程想要访问该控件,则应使用Invoke来使ui线程执行该工作。 这与通过使用UI线程从速度较慢的服务器读取50 GB的内存而不阻塞用户界面以及不使用能够使其快速回到处理窗口消息并使应用程序保持响应状态的东西这一想法完全不同

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM