2009-12-10 4 views
6

Die folgende Funktion wird zuerst X-Nachrichten von Twitter Firehose nach unten ziehen, aber sieht aus wie WebResponse Blöcke und verlässt nie die Funktion:Warum endet WebResponse niemals beim Lesen von 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(); 
} 

Aber die folgende funktioniert:

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(); 

} 

Was ich tue, falsch?

+0

Wissen Sie, wo es hängt? Können Sie einen Debugger anhängen und einen Stack-Trace bekommen? Aus der Hand, es ist nichts falsch mit Ihrem Code. Es kann sein, dass der Server sich schlecht benimmt oder ein Fehler in StreamReader auftritt. Sie könnten Techniken in http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html verwenden, um herauszufinden, was unter den Abdeckungen passiert. Das wäre ein guter Ausgangspunkt. – feroze

+0

Wenn ich die using-Anweisungen entfernen und durch reader.close() ersetzen, sehe ich das gleiche Problem, und der Netzwerkmonitor zeigt an, dass die App weiterhin Daten empfängt, aber nicht von reader.close() zurückkommt. PS - nur getestet auf Vista. – martimedia

+0

Ich kann es nicht reproduzieren (VS 2008 unter Windows 7 64bit). Es funktioniert total gut ... –

Antwort

3

Werfen Sie Ihre WebRequest als ein HttpWebRequest, dann vor der Pause Anruf request.Abort()

+0

Danke, Hinzufügen von request.Abort() hat den Trick, unabhängig von der WebRequest als HttpWebRequest. Nicht sicher, warum der ursprüngliche Code für einige arbeitete, würde aber stark empfehlen, fügen Sie anfrage.Abort zu ihrem Code, wenn sie auf einer breiten Palette von .NET-Clients ausgeführt werden möchten. – martimedia

+0

Ich verbrachte 12 Stunden damit, mir die Haare zu ziehen:^( –

-1

Sieht aus wie es etwas mit dem Entsorgungsprozess oder „Verwendung“ zu tun ...

Der folgende Code funktioniert gut (keine Aussagen „mit“):

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

Zustimmen, es wird weiter, aber nur, weil Sie die .NET-Garbage Collection verzögern. Wenn Sie die Funktion ein paar Mal ausführen, wird die Garbage Collection aktiviert und das Programm bleibt wie zuvor hängen. – martimedia