C#异步Http请求,如何停止跳过?

时间:2011-03-22 20:48:55

标签: c# asynchronous httpwebrequest

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()等...但是一旦跳过就没有任何反应。

3 个答案:

答案 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)