dotNet 自带线程池与HTTP访问的若干疑问
2009-08-10 18:52 清炒白菜 阅读(342) 评论(0) 编辑 收藏 举报
疑问:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
public static object Download1(object o)
{
HttpWebResponse response = null;
Stream ReceiveStream = null;
FileStream fs = null;
BinaryWriter w = null;
string ID = string.Empty;
try
{
byte[] nbytes = new byte[512];
DownFileArg arg = o as DownFileArg;
ID = arg.ID;
DownFileStat.AddTask(arg.ID);
string FILE_NAME = arg.FileName;
String PathInfo = arg.TargetPath + "\\" + FILE_NAME;
if (File.Exists(PathInfo))
{
FileInfo fi = new FileInfo(PathInfo);
if (fi.Length > 0)
{
//Console.WriteLine("File {0} Exists!", FILE_NAME);
return null;
}
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(arg.PicURL);
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 2.0.50727; TheWorld)";
request.Timeout = 20000;
response = (HttpWebResponse)request.GetResponse();
if (response.ContentType.IndexOf("image") < 0)
{
//返回的不是图片数据
//是否需要抛异常?
return null;
}
ReceiveStream = response.GetResponseStream();
fs = new FileStream(PathInfo, FileMode.Create);
w = new BinaryWriter(fs);
int nreadsize = ReceiveStream.Read(nbytes, 0, 512);
while (nreadsize > 0)
{
w.Write(nbytes, 0, nreadsize);
nreadsize = ReceiveStream.Read(nbytes, 0, 512);
}
}
catch (WebException webExcp)
{
// Get the WebException status code.
WebExceptionStatus status = webExcp.Status;
// If status is WebExceptionStatus.ProtocolError,
// there has been a protocol error and a WebResponse
// should exist. Display the protocol error.
if (status == WebExceptionStatus.ProtocolError)
{
// Get HttpWebResponse so that you can check the HTTP status code.
HttpWebResponse httpResponse = (HttpWebResponse)webExcp.Response;
ExceptionHelper.Write("The server returned protocol error " + ID + " " + (int)httpResponse.StatusCode + " - " + httpResponse.StatusCode);
}
}
catch (Exception e)
{
ExceptionHelper.Write(ID + " " + e.Message);
}
finally
{
DownFileStat.FinishTask(ID);
if (response != null)
{
response.Close();
}
if (w != null)
{
w.Close();
}
if (ReceiveStream != null)
{
ReceiveStream.Close();
}
if (fs != null)
{
fs.Close();
}
}
return null;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Args
public class DownFileArg
{
private string _picURL;
public string PicURL
{
get { return _picURL; }
}
private string _ID;
public string ID
{
get { return _ID; }
}
private string _TargetPath;
public string TargetPath
{
get { return _TargetPath; }
}
private string _fileName;
public string FileName
{
get { return _fileName; }
}
public DownFileArg(string jpgurl, string ID, string targetPath, string filename)
{
_picURL = jpgurl;
_ID = ID;
_TargetPath = targetPath;
_fileName = filename;
}
(To be continued)
1. 用HttpWebResponse的同步方式, 配合.NET自带的线程池, 从WEB上获取数据, 运行一段时间后, 被阻塞的线程会越来越多, 直到所有任务全部完成, 那些被阻塞的线程才会全部退出(自动)
2. 用HttpWebResponse的异步方式,直接产生大量任务(1w个), 则大约有20%的任务没有被处理, 而程序任务已经全部处理完毕.
针对上述2种情况, 换用SmartThreadPool来实现同样1w个任务, 则没有任何问题, 线程数稳定在40左右, 而且所有任务都完成了(发生异常,也算是执行了任务)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
public static object Download1(object o)
{
HttpWebResponse response = null;
Stream ReceiveStream = null;
FileStream fs = null;
BinaryWriter w = null;
string ID = string.Empty;
try
{
byte[] nbytes = new byte[512];
DownFileArg arg = o as DownFileArg;
ID = arg.ID;
DownFileStat.AddTask(arg.ID);
string FILE_NAME = arg.FileName;
String PathInfo = arg.TargetPath + "\\" + FILE_NAME;
if (File.Exists(PathInfo))
{
FileInfo fi = new FileInfo(PathInfo);
if (fi.Length > 0)
{
//Console.WriteLine("File {0} Exists!", FILE_NAME);
return null;
}
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(arg.PicURL);
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 2.0.50727; TheWorld)";
request.Timeout = 20000;
response = (HttpWebResponse)request.GetResponse();
if (response.ContentType.IndexOf("image") < 0)
{
//返回的不是图片数据
//是否需要抛异常?
return null;
}
ReceiveStream = response.GetResponseStream();
fs = new FileStream(PathInfo, FileMode.Create);
w = new BinaryWriter(fs);
int nreadsize = ReceiveStream.Read(nbytes, 0, 512);
while (nreadsize > 0)
{
w.Write(nbytes, 0, nreadsize);
nreadsize = ReceiveStream.Read(nbytes, 0, 512);
}
}
catch (WebException webExcp)
{
// Get the WebException status code.
WebExceptionStatus status = webExcp.Status;
// If status is WebExceptionStatus.ProtocolError,
// there has been a protocol error and a WebResponse
// should exist. Display the protocol error.
if (status == WebExceptionStatus.ProtocolError)
{
// Get HttpWebResponse so that you can check the HTTP status code.
HttpWebResponse httpResponse = (HttpWebResponse)webExcp.Response;
ExceptionHelper.Write("The server returned protocol error " + ID + " " + (int)httpResponse.StatusCode + " - " + httpResponse.StatusCode);
}
}
catch (Exception e)
{
ExceptionHelper.Write(ID + " " + e.Message);
}
finally
{
DownFileStat.FinishTask(ID);
if (response != null)
{
response.Close();
}
if (w != null)
{
w.Close();
}
if (ReceiveStream != null)
{
ReceiveStream.Close();
}
if (fs != null)
{
fs.Close();
}
}
return null;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class DownFileArg
{
private string _picURL;
public string PicURL
{
get { return _picURL; }
}
private string _ID;
public string ID
{
get { return _ID; }
}
private string _TargetPath;
public string TargetPath
{
get { return _TargetPath; }
}
private string _fileName;
public string FileName
{
get { return _fileName; }
}
public DownFileArg(string jpgurl, string ID, string targetPath, string filename)
{
_picURL = jpgurl;
_ID = ID;
_TargetPath = targetPath;
_fileName = filename;
}