C # Загрузить ошибку таймаута строки [duplicate]

Я пытаюсь загрузить данные клиента на свой локальный компьютер (программно), и их веб-сервер очень медленный, что вызывает таймаут в моем WebClient объекте.

Вот мой код:

WebClient webClient = new WebClient();

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

Есть ли способ установить бесконечный тайм-аут на этом объекте? Или, если нет, кто-нибудь может помочь мне с примером по альтернативному способу сделать это?

URL-адрес отлично работает в браузере - для отображения требуется всего около 3 минут.

185
задан 24 November 2009 в 15:59

6 ответов

Как говорит Sohnee, используя System.Net.HttpWebRequest и устанавливая свойство Timeout вместо использования System.Net.WebClient.

Вы не можете установить бесконечное значение таймаута (оно не поддерживается и не пытается сделать так что выкинет ArgumentOutOfRangeException).

Я бы рекомендовал сначала выполнить запрос System.Net.HttpWebRequest и изучить значение заголовка Content-Length, возвращаемое для определения количества байтов в файл, который вы загружаете, а затем устанавливаете значение таймаута соответственно для последующего запроса GET или просто указываете очень длинное значение таймаута, которое вы никогда не ожидаете превышать.

7
ответ дан 15 August 2018 в 15:50

Первое решение не сработало для меня, но вот какой-то код, который работал для меня.

    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);
        }
    }
10
ответ дан 15 August 2018 в 15:50

Для полноты, вот решение 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
7
ответ дан 15 August 2018 в 15:50
[F1]
7
ответ дан 15 August 2018 в 15:50

Не удалось заставить код 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);
}
8
ответ дан 15 August 2018 в 15:50
  • 1
    Этот ответ отлично работает, но для всех, кто интересуется, если вы используете var wresp = await request.GetResponseAsync(); вместо var wresp = (HttpWebResponse)request.GetResponse();, вы снова получите массовый таймаут – andrewjboyd 22 February 2018 в 10:00

Вам нужно использовать HttpWebRequest, а не WebClient, поскольку вы не можете установить тайм-аут на WebClient без его расширения (хотя он использует HttpWebRequest). Использование HttpWebRequest вместо этого позволит вам установить тайм-аут.

19
ответ дан 15 August 2018 в 15:50
  • 1
    Это неверно ... вы можете видеть выше, что вы все еще можете использовать WebClient, хотя и пользовательскую реализацию, которая переопределяет WebRequest для установки таймаута. – DomenicDatti 6 August 2014 в 18:21
  • 2
    «System.Net.HttpWebRequest.HttpWebRequest ()» устарел: «Этот API поддерживает инфраструктуру .NET Framework и не предназначен для использования непосредственно из вашего кода». – usefulBee 4 December 2014 в 00:24
  • 3
    @usefulBee - потому что вы не должны вызывать этот конструктор: "Do not use the HttpWebRequest constructor. Use the WebRequest.Create method to initialize new HttpWebRequest objects." из msdn.microsoft.com/en-us/library/… . Также см. [D1] stackoverflow.com/questions/400565/… – ToolmakerSteve 8 September 2015 в 16:13

Другие вопросы по тегам:

Похожие вопросы: