同时下载限制
我正在使用 WebRequest.BeginGetResponse 从服务器下载文件。一切都很好,但我不想同时下载 5 个文件。在 Java 中,我会使用固定线程池,但我不知道如何在 C# 中执行相同的操作。有什么想法吗?
class HttpFetcher
{
public void MakeRequest(Uri uri)
{
WebRequest request = WebRequest.Create(uri);
request.Proxy = null;
RequestState requestState = new RequestState();
requestState.Request = request;
IAsyncResult result = (IAsyncResult) request.BeginGetResponse(new AsyncCallback(ResponseCallback), requestState);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeOutCallback), request, 1000, true);
}
private void ResponseCallback(IAsyncResult result)
{
try
{
RequestState requestState = (RequestState)result.AsyncState;
WebRequest request = requestState.Request;
requestState.Response = request.EndGetResponse(result);
Stream responseStream = requestState.Response.GetResponseStream();
requestState.ResponseStream = responseStream;
IAsyncResult asynchronousResultRead = responseStream.BeginRead(requestState.BufferRead, 0, 1024, new AsyncCallback(ReadCallback), requestState);
}
catch (Exception ex)
{
Console.WriteLine("Exception raised!");
Console.WriteLine("Message : {0}", ex.Message);
RequestState state = (RequestState)result.AsyncState;
if (state.Response != null)
state.Response.Close();
}
}
private void ReadCallback(IAsyncResult result)
{
try
{
RequestState requestState = (RequestState)result.AsyncState;
Stream responseStream = requestState.ResponseStream;
int bytesRead = responseStream.EndRead(result);
if (bytesRead > 0)
{
requestState.RequestData.Append(Encoding.ASCII.GetString(requestState.BufferRead, 0, bytesRead));
IAsyncResult asynchronousResult = responseStream.BeginRead(requestState.BufferRead, 0, 1024, new AsyncCallback(ReadCallback), requestState);
}
else
{
Console.WriteLine("\nThe HTML page Contents are: ");
if (requestState.RequestData.Length > 1)
{
string sringContent;
sringContent = requestState.RequestData.ToString();
//Console.WriteLine(sringContent);
}
Console.WriteLine("\nPress 'Enter' key to continue........");
responseStream.Close();
}
}
catch (WebException e)
{
Console.WriteLine("WebException raised!");
Console.WriteLine("\n{0}", e.Message);
Console.WriteLine("\n{0}", e.Status);
}
catch (Exception e)
{
Console.WriteLine("Exception raised!");
Console.WriteLine("Source : {0}", e.Source);
Console.WriteLine("Message : {0}", e.Message);
}
}
private void TimeOutCallback(object state, bool timedOut)
{
if (timedOut)
{
WebRequest request = (WebRequest)state;
if (state != null)
{
request.Abort();
}
}
}
}
I'm making asynchronous requests with WebRequest.BeginGetResponse to download files from a server. All works nice but I want to download no more of 5 files at the same time. In Java I would use a fixed thread pool but I don't know how to do the same in C#. Any ideas?
class HttpFetcher
{
public void MakeRequest(Uri uri)
{
WebRequest request = WebRequest.Create(uri);
request.Proxy = null;
RequestState requestState = new RequestState();
requestState.Request = request;
IAsyncResult result = (IAsyncResult) request.BeginGetResponse(new AsyncCallback(ResponseCallback), requestState);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeOutCallback), request, 1000, true);
}
private void ResponseCallback(IAsyncResult result)
{
try
{
RequestState requestState = (RequestState)result.AsyncState;
WebRequest request = requestState.Request;
requestState.Response = request.EndGetResponse(result);
Stream responseStream = requestState.Response.GetResponseStream();
requestState.ResponseStream = responseStream;
IAsyncResult asynchronousResultRead = responseStream.BeginRead(requestState.BufferRead, 0, 1024, new AsyncCallback(ReadCallback), requestState);
}
catch (Exception ex)
{
Console.WriteLine("Exception raised!");
Console.WriteLine("Message : {0}", ex.Message);
RequestState state = (RequestState)result.AsyncState;
if (state.Response != null)
state.Response.Close();
}
}
private void ReadCallback(IAsyncResult result)
{
try
{
RequestState requestState = (RequestState)result.AsyncState;
Stream responseStream = requestState.ResponseStream;
int bytesRead = responseStream.EndRead(result);
if (bytesRead > 0)
{
requestState.RequestData.Append(Encoding.ASCII.GetString(requestState.BufferRead, 0, bytesRead));
IAsyncResult asynchronousResult = responseStream.BeginRead(requestState.BufferRead, 0, 1024, new AsyncCallback(ReadCallback), requestState);
}
else
{
Console.WriteLine("\nThe HTML page Contents are: ");
if (requestState.RequestData.Length > 1)
{
string sringContent;
sringContent = requestState.RequestData.ToString();
//Console.WriteLine(sringContent);
}
Console.WriteLine("\nPress 'Enter' key to continue........");
responseStream.Close();
}
}
catch (WebException e)
{
Console.WriteLine("WebException raised!");
Console.WriteLine("\n{0}", e.Message);
Console.WriteLine("\n{0}", e.Status);
}
catch (Exception e)
{
Console.WriteLine("Exception raised!");
Console.WriteLine("Source : {0}", e.Source);
Console.WriteLine("Message : {0}", e.Message);
}
}
private void TimeOutCallback(object state, bool timedOut)
{
if (timedOut)
{
WebRequest request = (WebRequest)state;
if (state != null)
{
request.Abort();
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用
Task.Factory.FromAsync()
并使用任务计划程序来限制并发无需深入探讨
FromAsync()
,这里是一个非常简化的示例,显示最多 5 个任务并行运行,无论有多少个任务排队:You could use
Task.Factory.FromAsync()
and use a Task Scheduler that limits the Degree of ConcurrencyWithout diving into
FromAsync()
here a very simplified example that shows that at most 5 tasks are running in parallel, regardless how many are queued: