C#程序在进行Web请求时停止处理

4

我对C#非常陌生,正在尝试编写一个基本程序。目标是在给定URL的情况下获取图像并将其保存到磁盘。

这就是我的代码基本超时的地方:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m.Value.Trim()); // url string passed in from Regex function
HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); // times out here

这段代码位于一个包含一个函数的类中,其运行方式如下:

 String url; // passed in as a parameter
 String folder = @"C:\SMBC";
 // create directory if not exists to save comic
 if(!Directory.Exists(folder)) 
     Directory.CreateDirectory(folder);

     // visit the site and check for comics
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
     request.Method = "GET";
     HttpWebResponse response = (HttpWebResponse)request.GetResponse();
     using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            while (reader.Peek() >= 0)
            {
                // if line contains "/comics/" then I'm in the right spot, we're at a URL now
                String line = reader.ReadLine();
                if (line.Contains("/comics/"))
                {
                    // pull out the address of the image // example result: http://www.smbc-comics.com/comics/20020905-2.gif
                    Regex linkParser = new Regex(@"\b(?:https?://|www\.)\S+\b", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                    foreach (Match m in linkParser.Matches(line))
                    {
                        // new local file in folder, use original file name
                        String name = @"" + folder +"\\" + m.Value.Substring(m.Value.LastIndexOf("/") + 1);
                        Console.WriteLine(m.Value.Trim()); //http://www.smbc-comics.com/comics/20020905-2.gif
                        Uri uri = new Uri(m.Value.Trim());
                        
                        Console.WriteLine("Making request"); // works 
                        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m.Value.Trim());
                        Console.WriteLine("getting response"); // works
                        HttpWebResponse resp = (HttpWebResponse) req.GetResponse();
                        Console.WriteLine("opening stream"); // never shows
                        using (Stream inputStream = resp.GetResponseStream())
                        using (Stream outputStream = File.OpenWrite(name))
                        {
                            byte[] buffer = new byte[4096];
                            int bytesRead;
                            do
                            {
                                bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                                outputStream.Write(buffer, 0, bytesRead);
                            } while (bytesRead != 0);
                            //outputStream.Close();
                            //inputStream.Close();
                            //resp.Close();
                        }
                    }
                }
            }
        }

我在控制台中运行此命令,以下是我得到的结果: enter image description here 一段时间后,操作就会超时,我知道该地址是有效的,因为我已经访问过它。
我是否漏掉了什么?

使用您的代码和相关网站首页的URL,我成功下载并保存了2个文件。 - spender
嗯...奇怪,感谢您查看@spender。 - SoluableNonagon
你在 Fiddler 中收到响应了吗? - fuzzybear
2
我不相信代理的问题,因为第一个请求没有任何问题。你的代码是否在所涉及的域上发生了未在问题中记录的请求?我注意到你没有在循环中关闭/处理响应……也许你达到了服务点连接限制? - spender
@spender,我向包含URL列表的域(档案页面)发出了一个先前的请求。通过循环遍历并执行上述代码来访问该列表中的每个URL。我不确定Servicepoint连接限制是什么(再次说明我对C#非常陌生)。 - SoluableNonagon
显示剩余5条评论
2个回答

2
我认为你遇到了 ServicePoint.ConnectionLimit 的限制。在开始之前,可以通过调整 ServicePointManager.DefaultConnectionLimit 来增加它。不要忘记在最小范围内处置所有可处置的东西...使用using语句是一个好习惯。如果你不关闭/处置WebRequest相关的内容,即使你认为请求已经完成,也会占用你的连接限制。

1
作为新手,我不知道框架在任何给定时间都允许有限数量的连接。因此,如果您在连接循环中有嵌套循环,则必须覆盖此限制。
ServicePointManager.DefaultConnectionLimit = 4;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接