【问题标题】:Set timeout for webClient.DownloadFile()为 webClient.DownloadFile() 设置超时
【发布时间】:2010-10-10 18:04:59
【问题描述】:

我正在使用webClient.DownloadFile() 下载文件,我可以为此设置一个超时时间,以便它无法访问该文件时不会花费很长时间?

【问题讨论】:

    标签: c# .net download webclient


    【解决方案1】:

    试试WebClient.DownloadFileAsync()。您可以使用自己的超时时间通过计时器调用CancelAsync()

    【讨论】:

    • 我不想使用计时器或秒表。我想要一些内置的 hack 或 api 方法。使用计时器/秒表会花费我额外的线程来观看,而这个功能可能已经实现了,所以为什么要重新发明轮子
    • @Kilanny:然后从另一个答案中选择解决方案。或者使用 HttpClient 并设置 Timeout 属性。另请注意,此答案来自 2009 年。
    • 在.Net 4.5+中你也可以使用var taskDownload = client.DownloadFileTaskAsync(new Uri("http://localhost/folder"),"filename")然后taskDownload.Wait(TimeSpan.FromSeconds(5));
    【解决方案2】:

    我的回答来自here

    您可以创建一个派生类,它将设置基类WebRequest 的超时属性:

    using System;
    using System.Net;
    
    public class WebDownload : WebClient
    {
        /// <summary>
        /// Time in milliseconds
        /// </summary>
        public int Timeout { get; set; }
    
        public WebDownload() : this(60000) { }
    
        public WebDownload(int timeout)
        {
            this.Timeout = timeout;
        }
    
        protected override WebRequest GetWebRequest(Uri address)
        {
            var request = base.GetWebRequest(address);
            if (request != null)
            {
                request.Timeout = this.Timeout;
            }
            return request;
        }
    }
    

    您可以像使用基础 WebClient 类一样使用它。

    【讨论】:

    • 以防其他人遇到这个有用的代码,我必须在调用 base.GetWebRequest(address) 之前设置超时
    • Resharper 抱怨“结果”可能存在空值,并建议在将超时值设置为 WebRequest 之前进行空值检查。查看反编译的代码,除非您在 web.config 中提供自定义 WebRequestModules 似乎是不可能的,但是对于这样一个赞成的答案,我会添加它以防万一。
    • 我在request.Timeout 这一行收到错误。错误消息'System.Net.WebRequest' does not contain a definition for 'Timeout' and no extension method 'Timeout' accepting a first argument of type 'System.Net.WebRequest' could be found (are you missing a using directive or an assembly reference?) ,我错过了什么?
    • @Eric:我添加了此代码 sn-p 使用的 using 指令。
    • @titol:使用 HttpClient 而不是 WebClient。
    【解决方案3】:

    假设您想同步执行此操作,使用 WebClient.OpenRead(...) 方法并在它返回的 Stream 上设置超时将为您提供所需的结果:

    using (var webClient = new WebClient())
    using (var stream = webClient.OpenRead(streamingUri))
    {
         if (stream != null)
         {
              stream.ReadTimeout = Timeout.Infinite;
              using (var reader = new StreamReader(stream, Encoding.UTF8, false))
              {
                   string line;
                   while ((line = reader.ReadLine()) != null)
                   {
                        if (line != String.Empty)
                        {
                            Console.WriteLine("Count {0}", count++);
                        }
                        Console.WriteLine(line);
                   }
              }
         }
    }
    

    从 WebClient 派生并覆盖 GetWebRequest(...) 以设置@Beniamin 建议的超时,这对我不起作用,但确实如此。

    【讨论】:

    • @jeffymorris 对我不起作用。即使我指定的 stream.ReadTimeout 大于执行请求的实际时间,我仍然会收到 WebException 说“请求已中止 - 操作已超时”
    • @jeffymoris 另一方面,带有 webclient 子类的解决方案也不起作用,所以它可能是服务器端的问题
    猜你喜欢
    • 2010-12-01
    • 2010-09-27
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 2015-12-17
    • 2019-03-27
    • 2011-12-14
    相关资源
    最近更新 更多