【问题标题】:Why using backgroundworker is not working good and sometimes i'm getting exceptions?为什么使用 backgroundworker 不能正常工作,有时我会遇到异常?
【发布时间】:2016-12-28 23:51:42
【问题描述】:

在 form1 中,我在另一个类中创建 List imagesUrls 后启动了 backgroundworker。

但是我在 dowork 事件和 progresschanged 事件中得到的是在 progressBar1 和 label2 上,我看到它按 10 计数:10,20,30,40....100% 然后是达到 100% 会引发异常。

例外:

附加信息:调用目标已引发异常。

例外是在Program.cs就行了:

Application.Run(new Form1());

我想要的是从列表 imagesUrls 下载每个文件,并将每个文件下载进度的 progressBar 和 label2 从 0% 更新到 100%,由 1 而不是 10:1、2、3、4、5.. .100 每个文件下载报告从 0 到 100 的下载进度

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.Threading;

namespace SatelliteImages
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            ExtractImages ei = new ExtractImages();
            ei.Init();

            backgroundWorker1.RunWorkerAsync();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 1; i <= ExtractImages.imagesUrls.Count(); i++)
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    using (var client = new WebClient())
                    {
                        client.DownloadFile(ExtractImages.imagesUrls[i], @"C:\Temp\TestingSatelliteImagesDownload\" + i + ".jpg");
                        System.Threading.Thread.Sleep(500);
                        worker.ReportProgress(i * 10);
                    }
                }
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            label2.Text = (e.ProgressPercentage.ToString() + "%");
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }
    }
}

然后我有我创建列表 imagesUrls 的类: 当我运行程序时,有时我会遇到异常而不是所有时间。

远程服务器返回错误:(500) Internal Server Error.

System.Net.WebException was unhandled
  HResult=-2146233079
  Message=The remote server returned an error: (500) Internal Server Error.
  Source=System
  StackTrace:
       at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
       at System.Net.WebClient.DownloadData(Uri address)
       at System.Net.WebClient.DownloadData(String address)
       at SatelliteImages.ExtractImages.ExtractDateAndTime(String baseAddress) in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\ExtractImages.cs:line 97
       at SatelliteImages.ExtractImages.Init() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\ExtractImages.cs:line 30
       at SatelliteImages.Form1..ctor() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Form1.cs:line 26
       at SatelliteImages.Program.Main() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

以及类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Xml;
using HtmlAgilityPack;

namespace SatelliteImages
{
    class ExtractImages
    {
        static WebClient client;
        static string htmltoextract;
        public static List<string> countriescodes = new List<string>();
        public static List<string> countriesnames = new List<string>();
        public static List<string> DatesAndTimes = new List<string>();
        public static List<string> imagesUrls = new List<string>();
        static string firstUrlPart = "http://www.sat24.com/image2.ashx?region=";
        static string secondUrlPart = "&time=";
        static string thirdUrlPart = "&ir=";

        public void Init()
        {
            ExtractCountires();
            foreach (string cc in countriescodes)
            {
                ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
            }
            ImagesLinks();
        }

        public static void ExtractCountires()
        {
            try
            {
                htmltoextract = "http://sat24.com/en/?ir=true";//"http://sat24.com/en/";// + regions;
                client = new WebClient();
                client.DownloadFile(htmltoextract, @"c:\temp\sat24.html");
                client.Dispose();

                string tag1 = "<li><a href=\"/en/";
                string tag2 = "</a></li>";

                string s = System.IO.File.ReadAllText(@"c:\temp\sat24.html");
                s = s.Substring(s.IndexOf(tag1));
                s = s.Substring(0, s.LastIndexOf(tag2) + tag2.ToCharArray().Length);
                s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");

                string[] parts = s.Split(new string[] { tag1, tag2 }, StringSplitOptions.RemoveEmptyEntries);


                string tag3 = "<li><ahref=\"/en/";

                for (int i = 0; i < parts.Length; i++)
                {
                    if (i == 17)
                    {
                        //break;
                    }
                    string l = "";
                    if (parts[i].Contains(tag3))
                        l = parts[i].Replace(tag3, "");

                    string z1 = l.Substring(0, l.IndexOf('"'));
                    if (z1.Contains("</ul></li><liclass="))
                    {
                        z1 = z1.Replace("</ul></li><liclass=", "af");
                    }
                    countriescodes.Add(z1);
                    countriescodes.GroupBy(n => n).Any(c => c.Count() > 1);

                    string z2 = parts[i].Substring(parts[i].LastIndexOf('>') + 1);
                    if (z2.Contains("&amp;"))
                    {
                        z2 = z2.Replace("&amp;", " & ");
                    }
                    countriesnames.Add(z2);
                    countriesnames.GroupBy(n => n).Any(c => c.Count() > 1);
                }
            }
            catch (Exception e)
            {

            }
        }

        public static void ExtractDateAndTime(string baseAddress)
        {
            var wc = new WebClient();
            wc.BaseAddress = baseAddress;
            HtmlDocument doc = new HtmlDocument();

            var temp = wc.DownloadData("/en");
            doc.Load(new MemoryStream(temp));

            var secTokenScript = doc.DocumentNode.Descendants()
                .Where(e =>
                       String.Compare(e.Name, "script", true) == 0 &&
                       String.Compare(e.ParentNode.Name, "div", true) == 0 &&
                       e.InnerText.Length > 0 &&
                       e.InnerText.Trim().StartsWith("var region")
                      ).FirstOrDefault().InnerText;
            var securityToken = secTokenScript;
            securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
            securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
            var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
            foreach (var date in scriptDates)
            {
                DatesAndTimes.Add(date.DateString);
            }
        }

        public class ScriptDate
        {
            public string DateString { get; set; }
            public int Year
            {
                get
                {
                    return Convert.ToInt32(this.DateString.Substring(0, 4));
                }
            }
            public int Month
            {
                get
                {
                    return Convert.ToInt32(this.DateString.Substring(4, 2));
                }
            }
            public int Day
            {
                get
                {
                    return Convert.ToInt32(this.DateString.Substring(6, 2));
                }
            }
            public int Hours
            {
                get
                {
                    return Convert.ToInt32(this.DateString.Substring(8, 2));
                }
            }
            public int Minutes
            {
                get
                {
                    return Convert.ToInt32(this.DateString.Substring(10, 2));
                }
            }
        }

        public void ImagesLinks()
        {
            int cnt = 0;
            foreach (string countryCode in countriescodes)
            {
                cnt++;
                for (; cnt < DatesAndTimes.Count(); cnt++)
                {
                    string imageUrl = firstUrlPart + countryCode + secondUrlPart + DatesAndTimes[cnt] + thirdUrlPart + "true";
                    imagesUrls.Add(imageUrl);
                    if (cnt % 10 == 0) break;
                }
            }
        }
    }
}

关于班级:

  1. 我应该如何处理异常?一般来说,我想通过再次尝试操作来处理,因为我会在每次 X 次时更新列表 imagesUrls,如果出现异常,请再次尝试操作而不是停止。

  2. 如何在 form1 中使用带有 backgroundworker 的类?因此,当它第一次在课堂上下载所有文件时,它也会在 form1 progressBar1 和 label2 上显示下载进度。

但首先要解决 form1 代码中的问题,然后还要处理类。

【问题讨论】:

  • 查看我关于进度条的回答here。我还提供了一个详细的示例来帮助您。
  • 您是否有来自服务器的日志(或某种获取更多详细信息的方式)?错误 500 很笼统。

标签: c# .net multithreading winforms


【解决方案1】:

对于您的进度问题:您的worker.ReportProgress(i * 10);行有错误。 i 的范围可以从 0ExtractImages.imagesUrls.Count()。因此,一旦 i 大于 10,您就报告了超过 100% 的进度。所以你正在检查你的进度条范围(如果你检查异常的内容,你可能应该在进度条值上有一个 Inner Exception = ArgumentException)。

替换为worker.ReportProgress(Math.Floor(100*i/ExtractImages.imagesUrls.Count())); 并确保您的进度条最大值为100。

对于第二个问题,你能确定是哪一行产生了错误吗?因为它是一个Error500,服务器端的问题。除非您有权访问服务器日志来识别源,否则您必须使用 try/catch 块来处理它,并管理有问题的条目(我认为只需忽略它们,并警告用户某些条目有问题是合理的第一种方法)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多