您实现的超时涉及获取响应,但不涉及包含所有数据并且通常需要更多时间才能实现的 ResponseStream。例如,获得响应通常需要不到 1 秒的时间,但下载网页内容可能需要几秒钟。
至于下载文件,您可以使用HttpWebRequest
getHttpWebResponse
和 from it 使用方法GetResponseStream()
来获取数据流。
这将很有帮助:
使用 HttpWebResponse 编码问题
特别byte[] buffer
是用于获取部分数据而不是StreamReader
ReadToEnd()
方法的部分。在将部分数据下载到缓冲区时,您可以根据超时 DateTime 检查当前 DateTime,从而允许在其后取消下载。
编辑:一段有用的代码
private byte[] DownloadFile( string uri, int requestTimeout, int downloadTimeout, out bool isTimeout, out int bytesDownloaded )
{
HttpWebRequest request = WebRequest.Create( uri ) as HttpWebRequest;
request.Timeout = requestTimeout;
HttpWebResponse response = null;
Stream responseStream = null;
MemoryStream downloadedData = null;
byte[] result = null;
bytesDownloaded = 0;
isTimeout = false;
try
{
// Get response
response = request.GetResponse() as HttpWebResponse;
byte[] buffer = new byte[ 16384 ];
// Create buffer for downloaded data
downloadedData = new MemoryStream();
// Set the timeout
DateTime timeout = DateTime.Now.Add( new TimeSpan( 0, 0, 0, 0, downloadTimeout ) );
// Read parts of the stream
responseStream = response.GetResponseStream();
int bytesRead = 0;
DateTime now = DateTime.Now;
while ( (bytesRead = responseStream.Read( buffer, 0, buffer.Length )) > 0 && DateTime.Now < timeout )
{
downloadedData.Write( buffer, 0, bytesRead );
now = DateTime.Now;
bytesDownloaded += bytesRead;
}
// Notify if timeout occured (could've been written better)
if ( DateTime.Now >= timeout )
{
isTimeout = true;
}
}
catch ( WebException ex )
{
// Grab timeout exception
if ( ex.Status == WebExceptionStatus.Timeout )
{
isTimeout = true;
}
}
finally
{
// Close the stream
if ( responseStream != null )
{
responseStream.Close();
}
}
if ( downloadedData != null )
{
result = downloadedData.GetBuffer();
downloadedData.Close();
}
return result;
}
用法
private void button1_Click( object sender, EventArgs e )
{
bool isTimeout;
int bytesDownloaded;
byte[] data = DownloadFile( something, 1000,500, out isTimeout, out bytesDownloaded );
MessageBox.Show( "Downloaded " + bytesDownloaded.ToString() + " bytes, Timeout = " + isTimeout.ToString() );
}
请记住,此代码仍然容易受到您可能遇到的其他异常的影响。