我该如何处理以及如何处理异常远程服务器返回错误:(500)内部服务器错误?

时间:2016-12-31 15:22:05

标签: c# .net winforms

大多数时候都会发生例外情况,但有时候工作正常。

异常始终相同

  

远程服务器返回错误:(500)内部服务器错误。

堆栈跟踪也是一样的:

  

在System.Net.WebClient.DownloadDataInternal(Uri地址,WebRequest和请求)
  在System.Net.WebClient.DownloadData(Uri地址)
  在System.Net.WebClient.DownloadData(字符串地址)
  位于D:\ C-Sharp \ SatelliteImages \ SatelliteImages \ SatelliteImages \ ExtractImages.cs中的SatelliteImages.ExtractImages.ExtractDateAndTime(String baseAddress):第120行

第120行是:

var temp = wc.DownloadData("/en");

方法:

public void ExtractDateAndTime(string baseAddress)
{
    try
    {
        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);
        }
    }
    catch(WebException wex)
    {
        if (wex.Response != null)
        {
            using (var errorResponse = (HttpWebResponse)wex.Response)
            {
                using (var reader = new StreamReader(errorResponse.GetResponseStream()))
                {
                    string error = reader.ReadToEnd();
                }
            }
        }

        countriescodes = new List<string>();
        countriesnames = new List<string>();
        DatesAndTimes = new List<string>();
        imagesUrls = new List<string>();

        this.Init();
    }
}

当我在线上使用断点时:

string error = reader.ReadToEnd();

我看到了html内容,在内容中我看到了文字:

  处理您的请求时出现

错误。返回Sat24.com的主页

我想要做的是以某种方式异常重新开始并尝试下载尝试方法ExtractDateAndTime

我认为使用计时器一些如何和倒计时显示用户类似30秒,然后再试一次。将30秒尝试将被视为服务器站点中的垃圾邮件/洪水?

这是完整的类代码,但此方法的例外是ExtractDateAndTime

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;
using System.ComponentModel;

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 class ProgressEventArgs : EventArgs
        {
            public int Percentage { get; set; }
            public string StateText { get; set; }
        }

        public event EventHandler<ProgressEventArgs> ProgressChanged;

        public void Init()
        {
            object obj = null;
            int index = 0;

            ExtractCountires();

            foreach (string cc in countriescodes)
            {
                // raise event here
                ProgressChanged?.Invoke(obj,new ProgressEventArgs{ Percentage = 100 * index / countriescodes.Count, StateText = cc });
                ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
                index +=1;
            }

            ImagesLinks();
        }

        public 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)
            {
                if (countriescodes.Count == 0)
                {
                    countriescodes = new List<string>();
                    countriesnames = new List<string>();
                    DatesAndTimes = new List<string>();
                    imagesUrls = new List<string>();
                    Init();
                }
            }
        }

        public void ExtractDateAndTime(string baseAddress)
        {
            try
            {
                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);
                }
            }
            catch(WebException wex)
            {
                if (wex.Response != null)
                {
                    using (var errorResponse = (HttpWebResponse)wex.Response)
                    {
                        using (var reader = new StreamReader(errorResponse.GetResponseStream()))
                        {
                            string error = reader.ReadToEnd();
                        }
                    }
                }

                            countriescodes = new List<string>();
                countriesnames = new List<string>();
                DatesAndTimes = new List<string>();
                imagesUrls = new List<string>();
                this.Init();
            }
        }

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

我想要的是在异常发生的情况下重新开始整个类操作。

在Form1中,我第一次启动类操作: 在顶部:

ExtractImages ei = new ExtractImages();

然后在构造函数中:

ei.Init();

问题是有时会发生此异常。

1 个答案:

答案 0 :(得分:0)

您可以使用PollyTransient Fault Handling Application Block之类的内容来为您的代码应用重试策略。

这两个软件包都为各种场景提供了多个开箱即用的组件,您可以随时开发自己的组件。一些包含的重试政策:

  • 增量
  • 固定间隔
  • 指数后退
  • 重试
  • 永远重试
  • 重试并等待
  • 等待并永远重试
  • ...