2008-11-17 64 views
6

在.NET中最好的方法是什麼? 我總是忘記我需要Dispose()(或換成using)。C#:下載超時的URL

編輯:經過很長時間使用WebRequest,我找到了關於定製WebClient。好多了。

回答

6

繼托馬斯·萊維斯克的評論here,還有一個更簡單,更通用的解決方案。

我們創建了一個WebClient子類,有超時支持,並且我們獲得了所有WebClient的好處。

public class WebClientWithTimeout : WebClient 
{ 
    private readonly int timeoutMilliseconds; 
    public WebClientWithTimeout(int timeoutMilliseconds) 
    { 
    this.timeoutMilliseconds = timeoutMilliseconds; 
    } 

    protected override WebRequest GetWebRequest(Uri address) 
    { 
    var result = base.GetWebRequest(address); 
    result.Timeout = timeoutMilliseconds; 
    return result; 
    } 
} 

使用範例:

public string GetRequest(Uri uri, int timeoutMilliseconds) 
{ 
    using (var client = new WebClientWithTimeout(timeoutMilliseconds)) 
    { 
    return client.DownloadString(); 
    } 
} 
10

下面是我用的東西,它似乎工作,但我不知道這是否是最好的辦法:

public string GetRequest(Uri uri, int timeoutMilliseconds) 
{ 
    var request = System.Net.WebRequest.Create(uri); 
    request.Timeout = timeoutMilliseconds; 
    using (var response = request.GetResponse()) 
    using (var stream = response.GetResponseStream()) 
    using (var reader = new System.IO.StreamReader(stream)) 
    { 
     return reader.ReadToEnd(); 
    } 
} 
+0

看起來不錯,我.. – 2008-11-17 13:30:49

+0

不壞的簡單的URL,不需要發送POST變量。您應該標記您使用Framework 3.5 ... – 2008-11-17 13:48:38

+0

我只使用生產代碼的異步請求。在我的答案中,你可以找到我從MSDN克隆的一個巨大的異步代碼,並添加了行myHttpWebRequest.ReadWriteTimeout = DefaultTimeout; – 2008-12-28 21:35:51

-5

運行System.Net.WebClient在一個單獨的線程,設置一個計時器,將其殺死在你最長的時間之後。

11

Syncronous方式:

var request = HttpWebRequest.Create("http://www.contoso.com"); 
request.Timeout = 50000; 
using (var response = request.GetResponse()) 
{ 
    //your code here 
} 

您還可以異步方式:

using System; 
using System.Net; 
using System.IO; 
using System.Text; 
using System.Threading; 


public class RequestState 
{ 
    // This class stores the State of the request. 
    const int BUFFER_SIZE = 1024; 
    public StringBuilder requestData; 
    public byte[] BufferRead; 
    public HttpWebRequest request; 
    public HttpWebResponse response; 
    public Stream streamResponse; 
    public RequestState() 
    { 
    BufferRead = new byte[BUFFER_SIZE]; 
    requestData = new StringBuilder(""); 
    request = null; 
    streamResponse = null; 
    } 
} 

class HttpWebRequest_BeginGetResponse 
{ 
    public static ManualResetEvent allDone = new ManualResetEvent(false); 
    const int BUFFER_SIZE = 1024; 
    const int DefaultTimeout = 2 * 60 * 1000; // 2 minutes timeout 

    // Abort the request if the timer fires. 
    private static void TimeoutCallback(object state, bool timedOut) 
    { 
     if (timedOut) 
     { 
      HttpWebRequest request = state as HttpWebRequest; 
      if (request != null) 
      { 
       request.Abort(); 
      } 
     } 
    } 

    static void Main() 
    { 

     try 
     { 
      // Create a HttpWebrequest object to the desired URL. 
      HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.contoso.com"); 
      myHttpWebRequest.ReadWriteTimeout = DefaultTimeout; 


      // Create an instance of the RequestState and assign the previous myHttpWebRequest 
      // object to its request field. 
      RequestState myRequestState = new RequestState(); 
      myRequestState.request = myHttpWebRequest; 


      // Start the asynchronous request. 
      IAsyncResult result = 
       (IAsyncResult)myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback), myRequestState); 

      // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted 
      ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), myHttpWebRequest, DefaultTimeout, true); 

      // The response came in the allowed time. The work processing will happen in the 
      // callback function. 
      allDone.WaitOne(); 

      // Release the HttpWebResponse resource. 
      myRequestState.response.Close(); 
     } 
     catch (WebException e) 
     { 
      Console.WriteLine("\nMain Exception raised!"); 
      Console.WriteLine("\nMessage:{0}", e.Message); 
      Console.WriteLine("\nStatus:{0}", e.Status); 
      Console.WriteLine("Press any key to continue.........."); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("\nMain Exception raised!"); 
      Console.WriteLine("Source :{0} ", e.Source); 
      Console.WriteLine("Message :{0} ", e.Message); 
      Console.WriteLine("Press any key to continue.........."); 
      Console.Read(); 
     } 
    } 
    private static void RespCallback(IAsyncResult asynchronousResult) 
    { 
     try 
     { 
      // State of request is asynchronous. 
      RequestState myRequestState = (RequestState)asynchronousResult.AsyncState; 
      HttpWebRequest myHttpWebRequest = myRequestState.request; 
      myRequestState.response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(asynchronousResult); 

      // Read the response into a Stream object. 
      Stream responseStream = myRequestState.response.GetResponseStream(); 
      myRequestState.streamResponse = responseStream; 

      // Begin the Reading of the contents of the HTML page and print it to the console. 
      IAsyncResult asynchronousInputRead = responseStream.BeginRead(myRequestState.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState); 
      return; 
     } 
     catch (WebException e) 
     { 
      Console.WriteLine("\nRespCallback Exception raised!"); 
      Console.WriteLine("\nMessage:{0}", e.Message); 
      Console.WriteLine("\nStatus:{0}", e.Status); 
     } 
     allDone.Set(); 
    } 
    private static void ReadCallBack(IAsyncResult asyncResult) 
    { 
     try 
     { 

      RequestState myRequestState = (RequestState)asyncResult.AsyncState; 
      Stream responseStream = myRequestState.streamResponse; 
      int read = responseStream.EndRead(asyncResult); 
      // Read the HTML page and then print it to the console. 
      if (read > 0) 
      { 
       myRequestState.requestData.Append(Encoding.ASCII.GetString(myRequestState.BufferRead, 0, read)); 
       IAsyncResult asynchronousResult = responseStream.BeginRead(myRequestState.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState); 
       return; 
      } 
      else 
      { 
       Console.WriteLine("\nThe contents of the Html page are : "); 
       if (myRequestState.requestData.Length > 1) 
       { 
        string stringContent; 
        stringContent = myRequestState.requestData.ToString(); 
        Console.WriteLine(stringContent); 
       } 
       Console.WriteLine("Press any key to continue.........."); 
       Console.ReadLine(); 

       responseStream.Close(); 
      } 

     } 
     catch (WebException e) 
     { 
      Console.WriteLine("\nReadCallBack Exception raised!"); 
      Console.WriteLine("\nMessage:{0}", e.Message); 
      Console.WriteLine("\nStatus:{0}", e.Status); 
     } 
     allDone.Set(); 

    } 
}