2009-12-10 20 views
6

La fonction suivante abattrai premiers messages X de Twitter firehose, mais ressemble à des blocs de WebResponse et ne jamais quitter la fonction:Pourquoi WebResponse ne se termine-t-il jamais lors de la lecture de twitter firehose stream?

public void GetStatusesFromStream(string username, string password, int nMessageCount) 
{ 
    WebRequest request = WebRequest.Create("http://stream.twitter.com/1/statuses/sample.json"); 
    request.Credentials = new NetworkCredential(username, password); 

    using (WebResponse response = request.GetResponse()) 
    { 
     using (var stream = response.GetResponseStream()) 
     { 
      using (var reader = new StreamReader(stream)) 
      { 
       while (!reader.EndOfStream) 
       { 
        Console.WriteLine(reader.ReadLine()); 

        if (nMessageCount-- < 0) 
         break; 
       } 
       Console.WriteLine("Start iDispose"); 
      } 
      Console.WriteLine("Never gets here!!!"); 
     } 
    } 

    Console.WriteLine("Done - press a key to exit"); 
    Console.ReadLine(); 
} 

Mais les travaux suivants bien:

public void GetStatusesFromStreamOK(string username, string password, int nMessageCount) 
    { 
    byte[] encbuff = System.Text.Encoding.UTF8.GetBytes(username + ":" + password); 
    //request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(encbuff)); 

    string requestString = "GET /1/statuses/sample.json HTTP/1.1\r\n"; 
    requestString += "Authorization: " + "Basic " + Convert.ToBase64String(encbuff) + "\r\n"; 
    requestString += "Host: stream.twitter.com\r\n"; 
    requestString += "Connection: keep-alive\r\n"; 
    requestString += "\r\n"; 

    using (TcpClient client = new TcpClient()) 
    { 
     client.Connect("stream.twitter.com", 80); 

     using (NetworkStream stream = client.GetStream()) 
     { 
      // Send the request. 
      StreamWriter writer = new StreamWriter(stream); 
      writer.Write(requestString); 
      writer.Flush(); 

      // Process the response. 
      StreamReader rdr = new StreamReader(stream); 

      while (!rdr.EndOfStream) 
      { 
       Console.WriteLine(rdr.ReadLine()); 
       if (nMessageCount-- < 0) 
        break; 
      } 

     } 
    } 

    Console.WriteLine("Done - press a key to exit"); 
    Console.ReadLine(); 

} 

Qu'est-ce que je fais faux?

+0

Savez-vous où il est suspendu? Pouvez-vous attacher un débogueur et obtenir une trace de pile? Désolé, il n'y a rien de mal avec votre code. Il se peut que le serveur se comporte mal, ou un bogue dans StreamReader. Vous pouvez utiliser des techniques dans http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html pour comprendre ce qui se passe sous les couvertures. Ce serait un bon point de départ. – feroze

+0

Si je supprime les instructions using et les remplace par reader.close() je vois le même problème, et le moniteur de réseau montre que l'application reçoit toujours des données mais ne renvoie pas de reader.close(). PS - comportement testé uniquement sur Vista. – martimedia

+0

Je ne peux pas le reproduire (VS 2008 sur Windows 7 64bit). Cela fonctionne totalement bien ... –

Répondre

3

Cast your WebRequest comme un HttpWebRequest, puis avant l'appel de rupture request.Abort()

+0

Merci, en ajoutant request.Abort() a fait l'affaire, sans tenir compte du WebRequest en tant que HttpWebRequest. Vous ne savez pas pourquoi le code d'origine a fonctionné pour certains, mais conseille vivement aux utilisateurs d'ajouter une demande. Abordez leur code s'ils veulent exécuter sur une large gamme de clients .NET. – martimedia

+0

J'ai passé 12 heures à me coiffer:^( –

-1

On dirait qu'il a quelque chose à voir avec le processus d'élimination ou "en utilisant" ...

Le code suivant fonctionne très bien (pas des déclarations "en utilisant"):

public static void GetStatusesFromStream(string username, string password, int nMessageCount) 
    { 
     WebRequest request = WebRequest.Create("http://stream.twitter.com/1/statuses/sample.json"); 
     request.Credentials = new NetworkCredential(username, password); 

     WebResponse response = request.GetResponse(); 
     { 
      var stream = response.GetResponseStream(); 
      { 
       var reader = new StreamReader(stream); 
       { 
        while (!reader.EndOfStream) 
        { 
         Console.WriteLine(reader.ReadLine()); 

         if (nMessageCount-- < 0) 
          break; 
        } 
       } 
       Console.WriteLine("Never gets here!!!"); 
      } 
     } 

     Console.WriteLine("Done - press a key to exit"); 
     Console.ReadLine(); 
    } 
+0

Acceptez-le, mais seulement parce que vous retardez la collecte de place. NET. Si vous exécutez la fonction plusieurs fois, la récupération de place commencera et le programme se bloquera comme avant. – martimedia