List<string> urls = this.populateRequestList();
this.Logger("Starting");
var reqs = urls.Select<string, WebRequest>(HttpWebRequest.Create).ToArray();
var iars = reqs.Select(req => req.BeginGetResponse(null, null)).ToArray();
var rsps = reqs.Select((req, i) => req.EndGetResponse(iars[i])).ToArray();
this.Logger("Done");
到目前为止我注意到的事情:
当我运行此代码时,“开始”显示在我的日志中,但“完成”从未显示。当我在调试器中查看整个过程时,它似乎跳过它就像它甚至不存在一样。也没有例外。当reqs.Select
循环遍历req.EndGetResponse(iars[i])
时,就像冻结或跳过某些东西一样。当我在调试器中查看它时,在它跳到最后之前我没有超过10-15个循环。
问题:
如何在var rsps = reqs.Select((req, i) => req.EndGetResponse(iars[i])).ToArray();
期间的某个时间停止“跳过”?
如何从rsps
获取HTML?我认为这样做的问题源于“跳过”。我尝试循环遍历每个响应并调用Repsponse.GetResponseStream()
等...但是一旦跳过就没有任何反应。
答案 0 :(得分:7)
代码的问题在于BeginGetResponse(null,null)接受回调作为操作完成时调用的第一个参数。此回调是应该调用EndGetResponse的地方。当您调用EndGetResponse时,操作尚未完成。
查看本文,了解如何使用迭代器在C#中创建异步Web请求:http://tomasp.net/blog/csharp-async.aspx。
如果使用任务并行库或.NET 4,您也可以这样做:
var urls = new List<string>();
var tasks = urls.Select(url =>
{
var request = WebRequest.Create(url);
var task = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
task.Start();
return task;
}).ToArray();
Task.WaitAll(tasks);
foreach (var task in tasks)
{
using (var response = task.Result)
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
var html = reader.ReadToEnd();
}
}
答案 1 :(得分:0)
您正在尝试使用异步请求方法执行同步请求,但这不起作用。
您应该使用BeginGetResponse
使用处理每个响应的回调方法来启动请求。如果您在EndGetResponse
之后立即致电BeginGetResponse
,它将会失败,因为响应尚未开始。
如果要发出同步请求,请改用GetResponse
方法。
答案 2 :(得分:0)
当我阅读http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.endgetresponse.aspx时,你需要等待回调才能使用EndGetResponse吗?
或使用GetReponse:http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx