2009-12-10 13 views
6

Poniższa funkcja będzie ciągnąć w dół pierwszych komunikatów X z Twittera Firehose, ale wygląda bloków WebResponse i nigdy nie wychodzi z funkcji:Dlaczego WebResponse nigdy się nie kończy po przeczytaniu strumienia w twitterze?

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

Ale następujący działa dobrze:

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

} 

Co robię źle?

+0

Czy wiesz, gdzie jest zawieszony? Czy możesz dołączyć debugger i uzyskać ślad stosu? Z drugiej strony, nie ma nic złego w tym kodzie. Możliwe, że serwer źle działa lub błąd w StreamReaderze. Możesz użyć technik w http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html, aby dowiedzieć się, co dzieje się pod kołdrą. To byłby dobry punkt wyjścia. – feroze

+0

Po usunięciu instrukcji using i zastąpieniu przez read.close() widzę ten sam problem, a monitor sieci pokazuje, że aplikacja nadal odbiera dane, ale nie wraca z read.close(). PS - testowane zachowanie tylko w systemie Vista. – martimedia

+0

Nie mogę go odtworzyć (VS 2008 na Windows 7 64bit). Działa całkowicie dobrze ... –

Odpowiedz

3

Oddaj swój WebRequest jako HttpWebRequest, a następnie przed przerwą dzwoni request.Abort()

+0

Dzięki, dodając request.Abort() zrobił lewę, niezależnie od castingu WebRequest jako HttpWebRequest. Nie jestem pewien, dlaczego oryginalny kod zadziałał dla niektórych osób, ale zdecydowanie zaleciłbym, aby dodali oni prośbę. Przeprowadź ich kod, jeśli chcą korzystać z szerokiej gamy klientów .NET. – martimedia

+0

Spędziłem 12 godzin ciągnąc mnie za włosy:^( –

-1

Wygląda na to, że ma coś wspólnego z procesem zbycia lub „za pomocą” ...

Poniższy kod działa poprawnie (nie „używając” sprawozdań):

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

Zgadzam się, że robi się jeszcze dalej, ale tylko dlatego, że opóźniasz odbiór śmieci .NET. Jeśli uruchomisz tę funkcję kilka razy, ładowanie śmieci zostanie uruchomione, a program zawiesi się jak poprzednio. – martimedia

Powiązane problemy