C# - 定期调用 HttpWebRequest 和 WebBrowser 的应用程序中的内存管理
C# - Memory management in a app that is periodicaly calling HttpWebRequest and WebBrowser
关于:
我有这个 Windows 表单应用程序,它每 60 秒从两个常用网页捕获信息,对结果进行一些简单的字符串处理,并根据结果执行(或不执行)某些操作。
其中一个站点没有任何保护,因此我可以使用 HttpWebRequest
轻松获取它的 HTML 代码,它是 HttpWebResponse.GetResponseStream()
。
另一个有一些代码保护,我不能使用相同的方法。解决方案是使用 WebBrowser
class 到 select 站点的所有文本并复制到剪贴板,如 Jake Drew 发布的 here(方法一).
额外信息:
当计时器达到1分钟时,使用Task
异步执行每个方法。在每个任务结束时,主线程将在这些文本中搜索一些信息,并根据结果做出或不做出一些决定。在此过程之后,即使是捕获的文本也不再相关。基本上所有的东西都可以从内存中清除,因为我会在大约 1 分钟内得到所有新的东西并处理它。
问题:
一切正常,但问题是它正在逐渐增加内存使用量(每次滴答约 20mb),这是不必要的,正如我之前所说的,我不需要在 运行 中维护数据内存比我在应用程序开始执行时多:
在比较两个快照后,我找到了这 3 个对象。显然他们要对内存使用过多负责:
所以,即使我将主要执行放在任务中并尽我所能帮助垃圾收集器,我仍然有这个问题。
我还能做些什么来避免这个问题或从内存中转储垃圾?
编辑:
这是使用 HttpWebRequest
捕获页面 HTML 的代码:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
if (response.StatusCode == HttpStatusCode.OK) {
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
if (response.CharacterSet == null) {
readStream = new StreamReader(receiveStream);
} else {
readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
}
PB_value = readStream.ReadToEnd();
readStream.Close(); //Ensure
}
response.Close(); //Ensure
}
已解决:
经过一番研究,我找到了解决方案。我其实有点惭愧,因为这是一个我以前没有尝试过的非常简单的解决方案,不过,分享还是很重要的。
我做的第一件事是创建一个 Event
来确定我的两个任务何时完成,然后我为这个事件分配了两个函数。第一个函数强制垃圾收集器 (GC.Collect()
)。第二个函数处理了两个任务,因为所有主要过程都在它们内部完成 (T.Dispose()
)。然后我得到了我想要的结果:
关于:
我有这个 Windows 表单应用程序,它每 60 秒从两个常用网页捕获信息,对结果进行一些简单的字符串处理,并根据结果执行(或不执行)某些操作。
其中一个站点没有任何保护,因此我可以使用 HttpWebRequest
轻松获取它的 HTML 代码,它是 HttpWebResponse.GetResponseStream()
。
另一个有一些代码保护,我不能使用相同的方法。解决方案是使用 WebBrowser
class 到 select 站点的所有文本并复制到剪贴板,如 Jake Drew 发布的 here(方法一).
额外信息:
当计时器达到1分钟时,使用Task
异步执行每个方法。在每个任务结束时,主线程将在这些文本中搜索一些信息,并根据结果做出或不做出一些决定。在此过程之后,即使是捕获的文本也不再相关。基本上所有的东西都可以从内存中清除,因为我会在大约 1 分钟内得到所有新的东西并处理它。
问题:
一切正常,但问题是它正在逐渐增加内存使用量(每次滴答约 20mb),这是不必要的,正如我之前所说的,我不需要在 运行 中维护数据内存比我在应用程序开始执行时多:
在比较两个快照后,我找到了这 3 个对象。显然他们要对内存使用过多负责:
所以,即使我将主要执行放在任务中并尽我所能帮助垃圾收集器,我仍然有这个问题。
我还能做些什么来避免这个问题或从内存中转储垃圾?
编辑:
这是使用 HttpWebRequest
捕获页面 HTML 的代码:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
if (response.StatusCode == HttpStatusCode.OK) {
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
if (response.CharacterSet == null) {
readStream = new StreamReader(receiveStream);
} else {
readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
}
PB_value = readStream.ReadToEnd();
readStream.Close(); //Ensure
}
response.Close(); //Ensure
}
已解决:
经过一番研究,我找到了解决方案。我其实有点惭愧,因为这是一个我以前没有尝试过的非常简单的解决方案,不过,分享还是很重要的。
我做的第一件事是创建一个 Event
来确定我的两个任务何时完成,然后我为这个事件分配了两个函数。第一个函数强制垃圾收集器 (GC.Collect()
)。第二个函数处理了两个任务,因为所有主要过程都在它们内部完成 (T.Dispose()
)。然后我得到了我想要的结果: