C#:使用超时下载URL
在.NET中最好的方法是什么? 我总是忘记我需要Dispose()
(或using
包装)。
编辑:经过很长一段时间使用WebRequest
,我发现了自定义WebClient
。 好多了。
同步方式:
var request = HttpWebRequest.Create("https://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("https://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(); } }
这是我使用的,它似乎工作,但我不知道这是否是最好的方式:
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(); } }
根据Thomas Levesque的评论, 这里有一个更简单,更通用的解决方案。
我们创建了一个具有超时支持的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(); } }
在一个单独的线程中运行System.Net.WebClient,设置一个计时器以在最长时间后终止它。
上述就是C#学习教程:C#:使用超时下载URL分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1043402.html