首页 文章

如何更改.NET WebClient对象的超时

提问于
浏览
197

我正在尝试将客户端的数据下载到我的本地计算机(以编程方式),并且他们的网络服务器非常非常慢,导致我的 WebClient 对象超时 .

这是我的代码:

WebClient webClient = new WebClient();

webClient.Encoding = Encoding.UTF8;
webClient.DownloadFile(downloadUrl, downloadFile);

有没有办法在这个对象上设置无限超时?或者,如果没有,任何人都可以用另一种方式帮助我做一个例子吗?

该URL在浏览器中正常工作 - 只需3分钟即可显示 .

7 回答

  • 8

    第一个解决方案对我不起作用,但这里有一些代码对我有用 .

    private class WebClient : System.Net.WebClient
        {
            public int Timeout { get; set; }
    
            protected override WebRequest GetWebRequest(Uri uri)
            {
                WebRequest lWebRequest = base.GetWebRequest(uri);
                lWebRequest.Timeout = Timeout;
                ((HttpWebRequest)lWebRequest).ReadWriteTimeout = Timeout;
                return lWebRequest;
            }
        }
    
        private string GetRequest(string aURL)
        {
            using (var lWebClient = new WebClient())
            {
                lWebClient.Timeout = 600 * 60 * 1000;
                return lWebClient.DownloadString(aURL);
            }
        }
    
  • 9

    拔出网线时无法使w.Timeout代码工作,它只是没有超时,转移到使用HttpWebRequest并立即完成工作 .

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(downloadUrl);
    request.Timeout = 10000;
    request.ReadWriteTimeout = 10000;
    var wresp = (HttpWebResponse)request.GetResponse();
    
    using (Stream file = File.OpenWrite(downloadFile))
    {
        wresp.GetResponseStream().CopyTo(file);
    }
    
  • 7

    您可以延长超时:继承原始WebClient类并覆盖webrequest getter以设置自己的超时,如下例所示 . 在我的案例中,MyWebClient是一个私有类

    private class MyWebClient : WebClient
        {
            protected override WebRequest GetWebRequest(Uri uri)
            {
                WebRequest w = base.GetWebRequest(uri);
                w.Timeout = 20 * 60 * 1000;
                return w;
            }
        }
    
  • 7

    您需要使用 HttpWebRequest 而不是 WebClient ,因为您无法在不扩展它的情况下在 WebClient 上设置超时(即使它使用 HttpWebRequest ) . 使用 HttpWebRequest 将允许您设置超时 .

  • 16

    为了完整起见,这里的kisp解决方案移植到VB(无法在注释中添加代码)

    Namespace Utils
    
    ''' <summary>
    ''' Subclass of WebClient to provide access to the timeout property
    ''' </summary>
    Public Class WebClient
        Inherits System.Net.WebClient
    
        Private _TimeoutMS As Integer = 0
    
        Public Sub New()
            MyBase.New()
        End Sub
        Public Sub New(ByVal TimeoutMS As Integer)
            MyBase.New()
            _TimeoutMS = TimeoutMS
        End Sub
        ''' <summary>
        ''' Set the web call timeout in Milliseconds
        ''' </summary>
        ''' <value></value>
        Public WriteOnly Property setTimeout() As Integer
            Set(ByVal value As Integer)
                _TimeoutMS = value
            End Set
        End Property
    
    
        Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
            Dim w As System.Net.WebRequest = MyBase.GetWebRequest(address)
            If _TimeoutMS <> 0 Then
                w.Timeout = _TimeoutMS
            End If
            Return w
        End Function
    
    End Class
    
    End Namespace
    
  • 341

    正如Sohnee所说,使用System.Net.HttpWebRequest并设置 Timeout 属性而不是使用 System.Net.WebClient .

    您可以't however set an infinite timeout value (it'不支持,尝试这样做会抛出 ArgumentOutOfRangeException ) .

    我建议首先执行HEAD HTTP请求并检查返回的 Content-Length 标头值以确定您正在下载的文件中的字节数,然后相应地为后续 GET 请求设置超时值,或者只是指定一个非常长的超时值永远不会超过 .

  • 20
    'CORRECTED VERSION OF LAST FUNCTION IN VISUAL BASIC BY GLENNG
    
    Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
                Dim w As System.Net.WebRequest = MyBase.GetWebRequest(address)
                If _TimeoutMS <> 0 Then
                    w.Timeout = _TimeoutMS
                End If
                Return w  '<<< NOTICE: MyBase.GetWebRequest(address) DOES NOT WORK >>>
            End Function
    

相关问题