2010-08-25 9 views
1

Il s'agit d'une application C# utilisant .NET 4.0.Exception non gérée lors du téléchargement d'une page Web à l'aide de HttpWebRequest et StreamReader

Contexte:

J'ai essayé d'affiner une partie d'une application qui permet de télécharger des fichiers à partir de plusieurs serveurs Web. Tout fonctionne plutôt bien sauf pour une situation occasionnelle où l'ordinateur distant ferme la connexion. Je suppose que cela peut être dû à une variété de facteurs, y compris les problèmes de réseau, les problèmes d'alimentation, etc. Je voudrais simplement ignorer le téléchargement dans le cas où la connexion se ferme. Toutefois, à l'heure actuelle, l'application provoque une exception qui est récupérée par le gestionnaire pour AppDomain.CurrentDomain.UnhandledException. La trace de la pile est la suivante:

Stack Trace:

Unable to read data from the transport connection: 
An existing connection was forcibly closed by the remote host. 
at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) 
at System.IO.StreamReader.ReadBuffer() at System.IO.StreamReader.ReadToEnd() 
at ProjectName.ClassNetwork.DownloadFile(String _IP, Int32 _Port, String _File) 
at ProjectName.FormMain.GetIFile(ClassSensor Sensor, String& RawHolder, String[] FileData) 
at ProjectName.FormMain.GetLegacyData(ClassSensor Sensor) 
at ProjectName.FormMain.threader_Download(Object SensorObject) 
at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ThreadHelper.ThreadStart(Object obj) 

j'avais à l'origine le try/catch pour la WebException et exception mais ils ne saisis pas cette erreur particulière. J'ai ajouté l'essai le plus intime/catch dans une tentative d'éviter le problème, mais en vain. Je dois mentionner que cette méthode est appelée par des threads autres que le thread d'interface utilisateur, ce qui peut expliquer en partie pourquoi les blocs try/catch ne semblent pas fonctionner. Pardonnez-moi d'être un novice quand il s'agit d'erreur multithread attraper!

Question:

  • Comment puis-je améliorer cette méthode et gérer correctement les situations où la connexion échoue en cours de route?

code:

private static object[] DownloadFile(string _IP, int _Port, string _File) 
{ 
    string uri = String.Format("http://{0}:{1}/{2}", _IP, _Port, _File); 
    string Status = String.Empty; 
    string Data = String.Empty; 
    HttpWebResponse Response = null; 

    try 
    { 
     HttpWebRequest webReq = (HttpWebRequest) WebRequest.Create(uri); 
     webReq.Timeout = 10000; 
     webReq.ReadWriteTimeout = 30000; 
     Response = (HttpWebResponse) webReq.GetResponse(); 
     using (Stream dataStream = Response.GetResponseStream()) 
      if (dataStream != null) 
       using (StreamReader reader = new StreamReader(dataStream)) 
        try 
        { 
         // This line causes crashes if remote computer closes connection 
         Data = reader.ReadToEnd(); 
        } 
        catch { } // Inner try/catch added to no avail 
     Response.Close(); 
    } 
    catch (WebException exc) 
    { 
     // Connection Error 
     Status = exc.Status.ToString(); 
     Data = String.Empty; 
    } 
    catch (Exception exc) 
    { 
     // Other error 
     Status = exc.Message; 
     Data = String.Empty; 
    } 

    if (Response != null && Response.StatusCode != HttpStatusCode.OK) 
    { 
     Status = Response.StatusCode.ToString(); 
     Data = String.Empty; 
    } 

    return new object[] { Status, Data }; 
} 

Trace Log:

suggestion de Per Feroze, j'ai couru point de trace, ce qui est le résultat:

System.Net Error: 0 : [2164] Exception in the 
#46104728::UnhandledExceptionHandler - Stream was not readable. 
System.Net Error: 0 : [2164]  at System.IO.BinaryReader..ctor(Stream input, Encoding encoding) 
at ProjectName.ClassNetwork.DLStream(ClassSensor Sensor) 
at ProjectName.ClassNetwork.DownloadFile(ClassSensor Sensor) 
at ProjectName.FormMain.GetStreamFile(ClassSensor Sensor) 
at ProjectName.FormMain.threader_Download(Object SensorObject) 
at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncctx) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ThreadHelper.ThreadStart(Object obj) 
+0

Je ne trouve aucun point d'interrogation indiquant qu'il y a une question à laquelle vous voulez également une réponse. –

+0

La dernière phrase, avant Le Code. Si vous préférez qu'il soit formulé comme une question: "Comment puis-je améliorer cette méthode et gérer correctement les situations où la connexion échoue à mi-chemin?" – JYelton

+0

Pouvez-vous publier la trace de la pile complète (non tronquée)? – feroze

Répondre

1

À partir de la pile, je ne vois pas comment cela est une exception lancée par un thread de threadpool que vous ne pouvez pas attraper. Évidemment, à partir de la pile, il semble que ce soit lancé par la méthode ConnectStream :: Read qui a été appelée sur votre thread d'application.

+0

Je voudrais créer le tracelog pour tenter de résoudre ce problème. Pouvez-vous fournir un peu plus d'informations sur le fichier de configuration à éditer? Votre blog suppose que j'en sais un peu plus que moi sur l'installation de tracelog. :) – JYelton

+0

Feroze, j'ai réussi à ajouter la capacité de tracelog à app.config. (Je n'étais pas sûr de ce que cela devait être au début.) L'erreur n'est pas prévisible mais devrait se produire dans les 24 heures. Ce sera un fichier énorme, donc je vais essayer de le couper à la section pertinente une fois que l'erreur se produit. Merci du coup de main jusqu'à présent. – JYelton

+0

J'ajoute les résultats du tracelog à ma question. – JYelton