0

我正在尝试通过 webclient 下载文件,代码如下所示。问题是,如果我多次收到连续的 404 响应,我的服务器会达到 100% 并且查看事件日志会告诉我发生了堆栈溢出。这里的“count”变量是为了避免 0 字节文件,count404 是为了 404 响应。

    int count = 0; int count404 = 0;
    public Stream DownloadFileThroughWebClient(string strFilePath)
    {
        try
        {
            if (count >= 120 || count404 >= 30)
            {
                count = 0;
                count404 = 0;
                return null;
            }
            System.Threading.Thread.Sleep(1000);
            System.Net.WebClient wc = new System.Net.WebClient();
            var v = wc.DownloadData(strFilePath);
            Stream FileToSave = new MemoryStream(v);
            byte[] bytes = new byte[FileToSave.Length];
            int numBytesToRead = (int)FileToSave.Length;
            if (numBytesToRead > 0)
            {
                count = 0;
                count404 = 0;
                return FileToSave;
            }
            else
            {
                count++;
                count404 = 0;
                return DownloadFileThroughWebClient(strFilePath);
            }
        }
        catch (Exception ex)
        {
            count++;
            count404++;
            return DownloadFileThroughWebClient(strFilePath);
        }
    }

提前致谢。

4

2 回答 2

1

你打电话:

return DownloadFileThroughWebClient(strFilePath);

如果出现问题。如果它不断收到 404(或更可能:因滥用查询而被 ip-blocked),那么您当然会使用 stackoverflow。如果您递归调用自己太多次,就会发生这种情况。所以:不要那样做。某种“while”循环(具有成功或持续失败的健全退出条件)似乎比递归更合适。

于 2012-09-23T10:30:33.680 回答
1

试试这个(不使用递归并正确计算 404):

public Stream DownloadFileThroughWebClient(string strFilePath)
{
    int count = 0; 
    int count404 = 0;

    while (count < 120 && count404 < 30)
    {
        try
        {
            byte[] v;
            using (var wc = new WebClient())
            {
                v = wc.DownloadData(strFilePath);
            }

            if (v.Length > 0)
            {
                return new MemoryStream(v);
            }

            count++;
            count404 = 0;
        }
        catch (WebException ex)
        {
            count++;
            var httpWebResponse = ex.Response as HttpWebResponse;
            if (httpWebResponse != null && httpWebResponse.StatusCode == HttpStatusCode.NotFound)
            {
                count404++;
                // you may wanna break out of the loop here since there's no point in continuing 
            }
        }
        catch (Exception ex)
        {

        }
    }
    return null;
}
于 2012-09-23T10:34:47.323 回答