C#:下载带有超时的 URL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/295557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: Downloading a URL with timeout
提问by orip
What's the best way to do it in .NET?
I always forget what I need to Dispose()
(or wrap with using
).
在 .NET 中执行此操作的最佳方法是什么?我总是忘记我需要什么Dispose()
(或用 包装using
)。
EDIT: after a long time using WebRequest
, I found out about customizing WebClient
. Much better.
编辑:使用了很长时间后WebRequest
,我发现了自定义WebClient
. 好多了。
采纳答案by orip
Following Thomas Levesque's comment here, there's a simpler and more generic solution.
遵循 Thomas Levesque 的评论here,有一个更简单、更通用的解决方案。
We create a WebClient
subclass with timeout support, and we get all of WebClient's goodness.
我们创建了一个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;
}
}
Sample usage:
示例用法:
public string GetRequest(Uri uri, int timeoutMilliseconds)
{
using (var client = new WebClientWithTimeout(timeoutMilliseconds))
{
return client.DownloadString();
}
}
回答by orip
Here's what I use, it seems to work, but I don't know if it's the best way:
这是我使用的,它似乎有效,但我不知道这是否是最好的方法:
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();
}
}
回答by buggs
Run System.Net.WebClient in a seperate thread, set a timer to kill it after your maximum time.
在单独的线程中运行 System.Net.WebClient,设置一个计时器以在您的最长时间后终止它。
回答by Jader Dias
Syncronous Way:
同步方式:
var request = HttpWebRequest.Create("http://www.contoso.com");
request.Timeout = 50000;
using (var response = request.GetResponse())
{
//your code here
}
You can also have the asynchronous way:
您还可以使用异步方式:
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();
}
}