我正在从数据库中读取Datagridview
约25000条记录。
在这个阅读过程中,应用程序处于“无响应”模式,我可以看到它的进程内存越来越大,停止在2500-3800 MB左右。
关闭包含Datagridview
的表单后,内存将保持此大小。
我的问题是:
从DB读取到Datagridview
:
delegate void SetSearchCallback();
public void Search()
{
sqlCommand="";
if (this._dbReports.InvokeRequired)
{
SetSearchCallback d = new SetSearchCallback(Search);
this.Invoke(d, new object[] { });
}
else
{
DateTime startDate = new DateTime(dateTimePicker1.Value.Year, dateTimePicker1.Value.Month, dateTimePicker1.Value.Day);
DateTime endDate = new DateTime(dateTimePicker2.Value.Year, dateTimePicker2.Value.Month, dateTimePicker2.Value.Day);
sqlCommand = "select * FROM cstPackages where _dateTime >= '" + String.Format("{0:yyyy-MM-dd}", startDate) + "' and _dateTime <='" + String.Format("{0:yyyy-MM-dd} 23:59:59.999", endDate) + "' order by _dateTime desc"; //reading the db from end to start
}
if (sqlCommand != "")
{
using (SqlConnection sCon2 = new SqlConnection("Data Source=" + SettingsForm.getAddress + ";Initial Catalog=" + SettingsForm.getDatabase + ";Integrated Security=False;User Id=" + SettingsForm.getUser + ";Password=" + SettingsForm.getPassword + ";Connect Timeout=5;"))
{
try
{
sCon2.Open();
using (da = new SqlDataAdapter(sqlCommand, sCon2))
{
dsReport.Clear();
da.Fill(dsReport, "cstPackages");
dbBind = new BindingSource(dsReport, "cstPackages");
if (firstTime == 0)
_dbReports.Columns.Clear();
_dbReports.DataSource = dbBind;
if (firstTime == 0)
{
updateDataGridSettings();
firstTime = 1;
}
_dbReports.Refresh();
sCon2.Close();
sCon2.Dispose();
}
}
catch (Exception c)
{
fn.errorHandler(c.Message, SettingsForm);
}
}
}
}
}
当我关闭表单时:{btnPress=1
只有当Datagridview
填充了某些内容时
private void Reports_FormClosing(object sender, FormClosingEventArgs e)
{
_dbReports.Dispose();
if (btnPress == 1)
{
dsReport.Dispose();
da.Dispose();
dbBind.Dispose();
}
}
在表单关闭后的父表单中,我正在调用ReportForm.Dispose();
我知道Dispose
并没有清除记忆,但它应该有助于GC做到这一点,对吗?
昨晚我把应用程序打开了一整夜(我关闭了ReportForm
后),早上的内存是相同的(GC没有用)
先谢谢。
修改 当我得到3GB内存泄漏时,我的数据库有大约500万条记录(我没有注意到,因为我的脚本填满了我的数据库,我忘了阻止它)
现在内存泄漏更容易被接受,它比我将记录添加到DataGridView之前大约多10 MB。 仍然..即使我正在使用虚拟模式并尝试关闭/处理我能做的一切,每个填充内存增长大约10 MB。
答案 0 :(得分:1)
1)当我读取大量数据时,如何避免“无响应”?
通过在单独的线程上执行这项昂贵的任务。在WinForms中,BackgroundWorker
非常有用,因为它会在作业完成后自动封送对主UI线程的调用。
2)如何减少我正在阅读时使用的内存量 数据库(我认为我做错了什么,因为它是一个 很多记忆)
您可以尝试启用Virtual Mode
并开始对数据进行分页。一次加载25000条记录毫无用处。无论如何,用户将无法立即使用它们。
3)关闭表单后如何清除所有内存?我正在处理 我能做的一切,但似乎GC仍未发布 记忆..我读了一些关于事件处理程序的东西 设置?
关闭表单后,垃圾收集器将负责处理所有资源。只需确保您从未存储任何对它的引用,以使其符合GC的条件。