2015-10-28 2 views
0

Я создаю собственный класс WebClient с некоторыми функциональными возможностями, которые недоступны в классе рамки WebClient. Я на самом деле с помощью этого класса, как это:Как повторить запрос веб-клиента, который получает исключение тайм-аута

using (var client = new CustomWebClient(10000)) 
{ 
    client.Tries = 5; //Number of tries that i want to get some page 
    GetPage(client); 
} 

CustomWebClient класс:

public class CustomWebClient : WebClient 
{ 
    public CookieContainer Cookies { get; } 
    public int Timeout { get; set; } 
    public int Tries { get; set; } 

    public CustomWebClient() : this(60000) 
    { 
    } 

    public CustomWebClient (int timeOut) 
    { 
     Timeout = timeOut; 
     Cookies = new CookieContainer(); 
     Encoding = Encoding.UTF8; 
    } 

    protected override WebRequest GetWebRequest(Uri address) 
    { 
     // some code here, but calling the base method 
    } 

    //this method actually is important to make the Tries logic. 
    protected override WebResponse GetWebResponse(WebRequest request) 
    { 
     try 
     { 
      return base.GetWebResponse(request); 
     } 
     catch (WebException ex) 
     { 
      if(ex.Status == WebExceptionStatus.Timeout || ex.Status == WebExceptionStatus.ConnectFailure) 
      if (--Tries == 0) 
       throw; 

      GetWebResponse(request); 
     } 
    } 

    } 

Когда заканчивается 10000 милисекунд, я base.GetWebResponse(request); бросает WebException с WebExceptionStatus.Timeout статус. И Tries вычитается. Но когда я выполняю команду GetWebResponse(request);, чтобы получить ответ, он не ждет 10000 миллисекунд и снова генерирует исключение, и оно продолжается до тех пор, пока не будет выполнено 5 попыток. Как получить ответ снова, сделав еще один запрос?

Спасибо.

+1

Вам нужно создать новый объект WebRequest. Просто повторное использование одного – Liam

+0

Да, я вижу, им просто нужно подумать о том, как сделать это прозрачно для клиента. – gog

ответ

1

Как отмечено в комментариях, вы повторно используете один и тот же объект WebRequest. Вы можете клонировать WebRequest объект с помощью кода из this ответа и передать клон base.GetWebResponse() Что-то вроде этого:

protected override WebResponse GetWebResponse(WebRequest request) 
{ 
    WebRequest deepCopiedWebRequest = ObjectCopier.Clone<WebRequest>(request); 
    try 
    { 
     return base.GetWebResponse(deepCopiedWebRequest); 
    } 
    catch (WebException ex) 
    { 
     if(ex.Status == WebExceptionStatus.Timeout || ex.Status == WebExceptionStatus.ConnectFailure) 
     if (--Tries == 0) 
      throw; 

     GetWebResponse(request); 
    } 
}