多部分下载超时

时间:2018-01-29 13:42:38

标签: c# httpwebrequest

我正在开发一个C#winform应用程序,它是由multypart异步下载的。 但是,有些部分会捕获请求超时错误。我尝试在我的应用程序工作时启动fiddler应用程序。我的应用程序正常工作,并为所有部分编译下载操作。 Fiddler对该计划的正常运作有何影响? 我写的代码中有没有遗漏的东西?

namespace Vektorel.DownloadManager
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            nmPartCount.Value = Environment.ProcessorCount;
            CheckForIllegalCrossThreadCalls = false;
        }

        void AddControl(FlowLayoutPanel panel, ucDownloadStatus download)
        {
            if (panel.InvokeRequired)
            {
                panel.Invoke(new Action<FlowLayoutPanel, ucDownloadStatus>(AddControl), panel, download);
            }
            else
            {
                panel.Controls.Add(download);
            }
        }

        void JoinParts()
        {
            DirectoryInfo di = new DirectoryInfo(Application.StartupPath);
            //exenin çalıştığı yerdeki part dosyalarının listesini alalım.
            FileInfo[] files = di.GetFiles().Where(f=>f.Name.Contains(".part")).ToArray();
            //partları birleştirmek için gereken stream
            FileStream fs = new FileStream(Path.GetFileName(txtUrl.Text), FileMode.Create);


            foreach (FileInfo file in files)
            {
                //ilgili part'a ait stream.
                FileStream partStream = new FileStream(file.Name, FileMode.Open);
                partStream.CopyTo(fs);
            }
            fs.Flush();
            fs.Close();
        }



        private void btnStartDownload_Click(object sender, EventArgs e)
        {
            HttpWebRequest requestForFileSize = (HttpWebRequest)HttpWebRequest.Create(txtUrl.Text);
            requestForFileSize.Method = "HEAD";
            long totalBytes = Convert.ToInt64(requestForFileSize.GetResponse().Headers["Content-Length"]);
            long partCount = Convert.ToInt64(nmPartCount.Value);
            long partSize = totalBytes / partCount;
            long startIndex = 0;
            Thread[] downloadThreads = new Thread[partCount];
            for (int i = 1; i <= partCount; i++)
            {

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(txtUrl.Text);
                request.Method = "GET";

                string partName = string.Format("part-{0}.part", i);

                if (i == partCount)
                {
                    partSize = totalBytes - startIndex;
                    request.AddRange(startIndex);                    
                }
                else
                {
                    request.AddRange(startIndex, startIndex + partSize);
                }

                startIndex = startIndex + partSize ;

                listBox1.Items.Add(totalBytes);
                listBox1.Items.Add(string.Format("{0} {1}", partName, partSize));

                downloadThreads[i - 1] = new Thread(() =>
                  {
                      byte[] buffer = new byte[1024];
                      FileStream fs = new FileStream(partName, FileMode.Create);

                      ucDownloadStatus downloadStatus = new ucDownloadStatus();
                      downloadStatus.PartName = partName;

                      AddControl(flowDownloadProgress, downloadStatus);

                      using (WebResponse response = request.GetResponse())
                      {
                          using (var responseStream = response.GetResponseStream())
                          {
                              int openedBytesLength = 0;
                              long totalBytesReceived = 0;
                              while ((openedBytesLength = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                              {
                                  fs.Write(buffer, 0, openedBytesLength);
                                  totalBytesReceived += openedBytesLength;
                                  int progressValue = (int)(totalBytesReceived * 100 / partSize);
                                  downloadStatus.Progress = progressValue;
                                  fs.Flush();
                              }
                          }
                      }
                      fs.Close();
                  });
            }

            for (int i = 0; i < downloadThreads.Length; i++)
            {
                downloadThreads[i].Start();
            }

            var complatedThread = new Thread(() =>
            {
                for (int i = 0; i < downloadThreads.Length; i++)
                {
                    downloadThreads[i].Join();
                }
                JoinParts();
            });
            complatedThread.Start();

        }
    }
}

2 个答案:

答案 0 :(得分:0)

尝试通过设置超时值来增加等待时间。

request.Timeout = 100;

其中100以毫秒为单位。

答案 1 :(得分:0)

下载zip文件时遇到一些问题,试试这个:

public class MyWebClient : WebClient
{


    protected override WebResponse GetWebResponse(WebRequest request)
    {

        (request as HttpWebRequest).AllowAutoRedirect = true;
        (request as HttpWebRequest).MaximumAutomaticRedirections = 100;
        (request as HttpWebRequest).UserAgent = @"Mozilla / 5.0(Windows; U; Windows NT 5.1; en - US; rv: 1.8.0.4) Gecko / 20060508 Firefox / 1.5.0.4";

        //CookieContainer make it work
        (request as HttpWebRequest).CookieContainer = new CookieContainer();

        WebResponse response = base.GetWebResponse(request);
        return response;
    }

    protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
    {

        (request as HttpWebRequest).AllowAutoRedirect = true;
        (request as HttpWebRequest).MaximumAutomaticRedirections = 100;
        (request as HttpWebRequest).UserAgent = @"Mozilla / 5.0(Windows; U; Windows NT 5.1; en - US; rv: 1.8.0.4) Gecko / 20060508 Firefox / 1.5.0.4";

        //CookieContainer make it work
        (request as HttpWebRequest).CookieContainer = new CookieContainer();

        WebResponse response = base.GetWebResponse(request, result);

        return response;

    }
}

使用:

client = new MyWebClient();


        //client.DownloadFile("http://www1.caixa.gov.br/loterias/_arquivos/loterias/D_mgsasc.zip", p1);
        client.DownloadFileCompleted += Client_DownloadFileCompleted1;    

        client.DownloadFileAsync(new Uri("http://example.com/file.zip"), path_name_to_save);

private static void Client_DownloadFileCompleted1(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        Console.WriteLine("download finished");
    }