我在Windows窗体中有一个下载程序,它下载了一堆URL的html源代码,并提取了更多的URL并下载了这些东西。我正在使用
using(WebClient client = new WebClient())
{
// Do download stuff here...
}
但.NET Mem Profiler显示严重的内存泄漏,因为很多对象都是垃圾收集但未处理或处置但未收集垃圾。听起来很奇怪,但我的程序有内存泄漏。
要了解我的计划,请考虑以下代码:
private void PreprocessURLs(List<string> URLs)
{
using(WebClient client = new WebClient())
{
// Download first batch of html source code and put in a List<string> property
}
}
private void ProcessURLs(List<string> URLs)
{
using(WebClient client = new WebClient())
{
// Download more stuff and save them
}
}
等等。这不是实际的程序,但我想告诉你的是,如何创建一个“全局”可用的WebClient对象/实例,这样我就不会创建一堆客户端对象?我想重用它。我怀疑这是导致内存泄漏的原因(可能是其中之一)。也许我错了,因为我从来没有创建过一个可能会导致内存泄漏的程序。
编辑:在建议使用tlemster之后,我创建了一个WebClient的静态实例但由于不支持并发I / O而导致I / O错误(DownloadFileAsync())。EDIT1:这是我的下载方法,它通过这样做来完成主要工作并阻止我的UI线程。因此我相信mem泄漏来自这个功能。
private void Download()
{
var stopwatch = new Stopwatch();
string bla;
string chapterName;
string bla1;
string chapterNumber;
List<Tuple<string, int>> temp = new List<Tuple<string, int>>();
// Contains all URLs from preprocessing
foreach (var chapter in Chapters)
{
bla = chapter.Item2;
chapterName = ReplaceSpecialChars(bla);
bla1 = chapter.Item3;
chapterNumber = ReplaceSpecialChars(bla1);
// Skip this chapter if it already exists based on chapter name
if (Directory.Exists(string.Format("{0}/{1} - {2}", chapter.Item4, chapterNumber, chapterName)))
{
continue;
}
else
{
Directory.CreateDirectory(string.Format("{0}/{1} - {2}", chapter.Item4, chapterNumber, chapterName));
}
// Process each chapter and extract other URLs
foreach (var item in GetPagesLink(chapter.Item1))
{
// Add the extracted URLs to a list for download further down
temp.Add(new Tuple<string, int>(GetImageLink(item.Item1), item.Item2));
}
stopwatch.Start();
// The download of the files I want after processing it two times
foreach (var img in temp)
{
// A static WebClient does not work because DownloadFileAsync() does not support concurrent I/O
// Atm should not matter because this whole thing is not async anyway...
using (WebClient webClient = new WebClient())
{
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync(new Uri(img.Item1), string.Format("{0}/{1} - {2}/{3}.jpg", chapter.Item4, chapterNumber, chapterName, img.Item2)); // TODO: Find image type and replace hardcoded jpg
System.Threading.Thread.Sleep(150);
}
}
stopwatch.Stop();
temp.Clear();
txtDebug.AppendText("Finished chapter " + chapter.Item3 + " : " + stopwatch.ElapsedMilliseconds + "\r\n");
stopwatch.Reset();
}
Chapters.Clear();
}
答案 0 :(得分:-1)
将创建的WebClient存储在一个静态字段中,只要程序正在运行或者直到你手动删除它,它就会使实例保持活动状态。