2009-08-05 7 views
1

J'utilise webrequest pour aller chercher des données d'image. L'URL peut être invoquée parfois. En cas d'URL invalide, begingetresponse prend un temps égal à la période de timeout. De plus, le contrôle ne répond plus pendant cette période. En d'autres termes, le rappel asynchrone ne fonctionne pas de manière asynchrone. Est-ce que ce comportement est attendu?webrequest.begingetresponse prend trop de temps lorsque l'url est invalide

try 
           { 
            // Async requests 
            WebRequest request = WebRequest.Create(uri); 
            request.Timeout = RequestTimeOut; 
            RequestObject requestObject = new RequestObject(); 
            requestObject.Request = request; 
            request.BeginGetResponse(this.ProcessImage, requestObject); 
           } 
           catch (Exception) 
           { 
            ShowErrorMessage(uri); 
           } 

private void ProcessImage(IAsyncResult asyncResult) 
     {    
      try 
      { 
       RequestObject requestObject = (RequestObject)asyncResult.AsyncState; 
       WebRequest request = requestObject.Request; 
       WebResponse response = request.EndGetResponse(asyncResult); 

       Bitmap tile = new Bitmap(response.GetResponseStream()); 
       // do something 
      } 
      catch (Exception) 
      { 
       ShowErrorMessage(); 
      } 
     } 
+0

Non, le comportement attendu serait que l'interface utilisateur reste réactive si vous utilisez BeginGetResponse. Pourriez-vous nous montrer un extrait du code où vous appelez BeginGetResponse? – bernhof

+0

Avez-vous un moyen de valider cette URL avant de l'envoyer? Je présume que le serveur que vous demandez est une boîte noire pour vous, n'avez pas accès à ce code? – Sebastian

+0

Je pense que je dois valider l'URL avant de l'utiliser plutôt que d'utiliser aveuglément l'URL. Je dois écrire plus de code :( – malay

Répondre

2

ressemble à ceci est un problème avec .NET. BeginGetResponse se bloque jusqu'à ce que DNS soit résolu. En cas de mauvaise URL (comme http://somecrap) il essaye jusqu'à ce qu'il obtienne le délai. Voir les liens suivants - link1 et link2

1

Je viens juste de rencontrer cette même situation. Bien que ce ne soit pas une solution de contournement parfaite, j'ai décidé d'utiliser Ping.SendAsync() pour faire un ping sur le site en premier. La bonne partie est la partie asynchrone immédiatement. Une mauvaise partie est l'étape supplémentaire ET tous les sites ne répondent pas aux requêtes Ping.

public void Start(WatchArgs args) 
{ 
     var p = new System.Net.NetworkInformation.Ping(); 
     args.State = p; 
     var po = new System.Net.NetworkInformation.PingOptions(10, true); 
     p.PingCompleted += new PingCompletedEventHandler(PingResponseReceived); 
     p.SendAsync(args.Machine.Name, 5 * 1000, Encoding.ASCII.GetBytes("watchdog"), po, args); 
} 

private void PingResponseReceived(object sender, .PingCompletedEventArgs e) 
{ 
    WatchArgs args = e.UserState as WatchArgs; 
    var p = args.State as System.Net.NetworkInformation.Ping; 
    p.PingCompleted -= new System.Net.NetworkInformation.PingCompletedEventHandler(HttpSmokeWatcher.PingResponseReceived); 
    args.State = null; 
    if (System.Net.NetworkInformation.IPStatus.Success == e.Reply.Status) 
    { 
     // ... BeginGetResponse now 
    } 
    else 
    { 
     /// ... machine not available 
    } 
} 

Juste code et en cours d'exécution pour un jour mais le résultat initial semble prometteur.

+0

Merci, c'est vraiment utile. – malay

Questions connexes