2011-10-19 9 views
6

Bağlantıda çok uzun sürdüğünde bir httpwebrequest sonlandırmak istiyorum.C# HttpWebRequest Bağlantısı nasıl sonlandırılır? Hatta zaman aşımı veya readwritetimeout çalışmaz çalışmıyor

  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); 
      request.Timeout = 5000; 
      request.ReadWriteTimeout = 5000; 
      request.Proxy = new WebProxy("http://" + proxyUsed + "/", true); 
      request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.01; Windows NT 5.0)"; 

      using (WebResponse myResponse = request.GetResponse()) 
      {      
       using (Stream s = myResponse.GetResponseStream()) 
       { 
        s.ReadTimeout = 5000; 
        s.WriteTimeout = 5000; 
        using (StreamReader sr = new StreamReader(s, System.Text.Encoding.UTF8)) 
        {        
         result = sr.ReadToEnd(); 
         httpLink = myResponse.ResponseUri.AbsoluteUri; 
         sr.Close(); 
        } 
        s.Close(); 
       } 
       myResponse.Close(); 
      } 

Ancak bazen bağlantı yanıt almak için bir yaklaşık 15dakika sürecektir: İşte yazdım sadece simaple kodudur. Durum 15 dakika sonra hala yanıtı alabilirim ancak URL'nin tam kaynak kodunu alamıyorum. Bağlantı çok yavaş olduğunu ve URL'nin bana zaman aşımı içinde biraz veri vereceğini sanırım, örneğin 5 saniyede 1 byte al, bu nedenle zaman aşımını geçmez ama çok uzun. Bağlantıyı nasıl sonlandırabilirim? Teşekkürler :)

cevap

2

Akış okumasını azaltın ve toplam süre çok uzunsa iptal edin.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); 
request.Timeout = 5000; 
request.ReadWriteTimeout = 5000; 
request.Proxy = new WebProxy("http://" + proxyUsed + "/", true); 
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.01; Windows NT 5.0)";//ahem! :) 
DateTime giveUp = DateTime.UtcNow.AddSeconds(5); 
using (WebResponse myResponse = request.GetResponse()) 
{      
    httpLink = myResponse.ResponseUri.AbsoluteUri; 
    using (Stream s = myResponse.GetResponseStream()) 
    { 
     s.ReadTimeout = 5000; 
     s.WriteTimeout = 5000; 
     char[] buffer = new char[4096]; 
     StringBuilder sb = new StringBuilder() 
     using (StreamReader sr = new StreamReader(s, System.Text.Encoding.UTF8)) 
     {        
      for(int read = sr.Read(buffer, 0, 4096); read != 0; read = sr.Read(buffer, 0, 4096)) 
      { 
       if(DateTime.UtcNow > giveUp) 
        throw new TimeoutException(); 
       sb.Append(buffer, 0, read); 
      } 
      result = sb.ToString(); 
     } 
    } 
} 
4

Sen aşımı aslında çalıştığını bulabilir, ama akışını kapatmak çalışırken iplik kapatır. Neden olduğunu bilmiyorum ama bazen öyle. ReadToEnd'u hiç kullanmadım, ancak Read'u kullanırken bununla karşılaşıyorum.

Sorunu kapatmadan önce, istek üzerine Abort numaralı telefonu arayarak sorunu çözdüm. Bu biraz zor ama etkili. Aşağıdaki kısaltılmış kod tekniği göstermektedir.

HttpWebResponse response = null; 
StreamReader sr = null; 
try 
{ 
    response = (HttpWebResponse)request.GetResponse(...); 
    Stream s = response.GetResponseStream(); 
    sr = new StreamReader(s, Encoding.UTF8); 
    // do your reading here 
} 
finally 
{ 
    request.Abort(); // !! Yes, abort the request 
    if (sr != null) 
     sr.Dispose(); 
    if (response != null) 
     response.Close(); 
} 

Ne buldum ReadTimeout ve ReadWriteTimeout eser beklendiği gibi olmasıdır. Yani, zaman aşımına uğradığında, yürütme gerçekten finally bloğuna gider. Ve request.Abort orada değilse, sr.Dispose numaralı çağrı asılacaktır.