2012-07-31 60 views
0

我得到連續 [不停]從網頁的url mesages:無法關閉的StreamReader(reader.Close();塊碼)

string webUrl = "xxxxx/status.cgi"; 
    WebClient client = new WebClient(); 
    client.Credentials = new NetworkCredential("UUU", "PPP"); 

    StreamReader reader = new StreamReader(client.OpenRead(webUrl), Encoding.UTF8,true); 
    string line; 
    int counter = 0; 
    while ((line = reader.ReadLine()) != null) 
    { 
     if(line == "XXXXXX") 
     { 
      break; 
     } 
    } 


    Console.WriteLine("Try to Close Stream Reader..."); 
    reader.Close(); 
    Console.WriteLine("Stream Reader is closed..."); 

的問題是,當我從while循環打破,我想關閉流式閱讀器...但流式閱讀器不關閉....「reader.Close();」掛起/阻止代碼...

爲什麼會發生這種情況?如何解決它?

UPDATE: 「使用」不工作在我的情況:退出循環,但流讀取器沒有設置...航/砌塊

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net; 
using System.Linq; 
using System.Text; 

namespace TestStreamReader 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string webUrl = "http://X.Y.Z:7000/status.cgi"; 
      int counter = 0; 

      using (WebClient client = new WebClient()) 
      { 
       client.Credentials = new NetworkCredential("admin", "000000"); 

       using (StreamReader reader = new StreamReader(client.OpenRead(webUrl), Encoding.UTF8, true)) 
       { 
        string line; 
        while ((line = reader.ReadLine()) != null) 
        { 
         counter++; 

         Console.WriteLine("Input"+ line); 

         if (counter == 10) 
         { 
          Console.WriteLine("I am exiting the loop"); 
          break; 
         } 


        } 

        Console.WriteLine("Exit the while loop"); 

       } 

       Console.WriteLine("Reader should be desposed"); 
      } 

      Console.WriteLine("Web Client should be disposed!"); 



     } 
    } 
} 
+1

先關閉webclient? – 2012-07-31 14:20:57

+0

您是否收到錯誤或異常?如果是這樣,那是什麼? – Kevin 2012-07-31 14:23:56

+0

WebClient沒有「關閉方法」...但我做了同樣的HttpWebResponse具有接近的方法...不改變任何東西... – Novalis 2012-07-31 14:24:55

回答

0

除了使用WebClient之外,您是否考慮過使用HttpWebRequest並獲取響應流?

//using System.Net; 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ApiProcedure.FunctionUri); 
    request.Credentials = (CredentialCache)Credentials; 
    request.PreAuthenticate = true; 

    //define the type of request 
    request.Method = HttpMethod; 
    request.ContentType = "application/json"; 

    //execute 
    StreamReader sr = new StreamReader(response.GetResponseStream()); 
    return sr.ReadToEnd(); 

我知道你正在做一個連續的流,但你應該能夠像在你的例子中一樣對待流讀取器。我認爲這種方法會給你更多的控制權。

我通常只使用WebClient,如果我需要執行一個簡單的任務,其中爲我完成所有基本設置/流。在分別管理請求和響應時查找更好的結果。

祝你好運!

編輯:此外,這只是從我的代碼片段。你可能想看看這裏:C# - How to read a continuous stream of XML over HTTP是一個閱讀連續數據塊的好例子。

+0

我嘗試使用HttpWebRequest和Response ...和ReadToEnd也阻止,因爲數據永遠不會結束...不起作用 – Novalis 2012-07-31 16:47:29

+0

@Novalis:D發送數據的服務器是否禁用了緩衝區,以便連續傳輸數據? http://msdn.microsoft.com/en-us/library/system.web.httpresponse.buffer.aspx – jamesbar2 2012-07-31 17:51:34

+2

那麼,我用HttpWebRequest /HttpWebResponse ....而不是request.Close()我打電話請求。 Abort()然後我可以關閉流式閱讀器......我不知道爲什麼「關閉」不起作用,但「中止」工作... – Novalis 2012-08-01 14:27:57

0

一個快速的想法FRM我的身邊,儘量把StreamReader的在使用中。

 string webUrl = "http://www.google.com"; 
     using (WebClient client = new WebClient()) 
     { 
      client.Credentials = new NetworkCredential("UUU", "PPP"); 

      int counter = 0; 

      using (StreamReader reader = new StreamReader(client.OpenRead(webUrl), Encoding.UTF8, true)) 
      { 
       string line; 
       while ((line = reader.ReadLine()) != null) 
       { 
        if (line == "XXXXXX") 
        { 
         break; 
        } 
        counter++; 
       } 

      } 
     } 

     Console.WriteLine("Try to Close Stream Reader..."); 
     Console.WriteLine("Stream Reader İSclosed..."); 

這將保持連接打開,直到它不再使用。 Dispose()將在那之後自動調用。無需手動分離或關閉。 [更新]我也將WebClient移動到StreamReaders之外的using和counter變量中。

[編輯]
由於評論問題看起來像WebClient的(未經測試的推測)副作用無法退出,因爲它無法看到流的末尾。因此,StreamReader在等待。我附上另一種從webrequest讀取的方法。但是,這遠遠不能肯定會更好。

string webUrl = "http://www.google.com"; 

    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(webUrl); 
    req.Credentials = new NetworkCredential("UUU", "PPP"); 
    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) 
    { 
     using (Stream stream = resp.GetResponseStream()) 
     { 
      int read; 
      string line; 

      byte[] data = new byte[4096]; 
      while ((read = stream.Read(data, 0, data.Length)) > 0) 
      { 
       line = Encoding.GetEncoding("ASCII").GetString(data, 0, data.Length); 

       if (line.Contains("(function(){try{var a=window.gbar;")) 
       { 
        Console.WriteLine("End Bit founded.."); 
        // Some more logic? 
        break; 
       } 
       data = new byte[4096]; 
       Console.WriteLine(line); 
      } 
     } 
    } 
    Console.WriteLine("End of Stream"); 

請注意我在這裏使用了Stream並手動拆分爲4096個數據塊,僅僅是爲了解決問題。通常會是using (StreamReader stream2 = new StreamReader(resp.GetResponseStream())) { string test = stream2.ReadToEnd(); }

希望它會進一步。
另外請注意,上面的編碼設置爲「ASCII」。

+0

這將在最後調用Dispose,它只是調用Close。它會導致同樣的事情。只有區別將被封鎖*在第一個Console.WriteLine – 2012-07-31 14:31:43

+0

@Peter之前*當然,它在Dispose()上調用Close()。使用讓.NET處理生命時間。 – Independent 2012-07-31 14:33:36

+0

沒有什麼變化......處置調用關閉...並阻止... – Novalis 2012-07-31 14:34:43

0

我見過類似的東西。問題在於它正在等待ReadTimeOut發生。您可以嘗試將Stream.ReadTimeOut屬性設置爲足夠小的值。

1

我有同樣的問題,但沒有在這個線程中提出的建議對我有幫助。但是我能夠以不同的方式修復它,所以我想我會分享......

我使用異步版本client.OpenRead(uri)來打開流,然後當我需要關閉它時,我可以調用client.CancelAsync()。在那裏的實現必須以不同的方式處置StreamReader,因爲它以這種方式工作。