我有一个 2 窗格 C# 应用程序,左侧是树,右侧是窗格。单击树节点会导致自定义 UserControl 显示在右侧。我在这个应用程序中有几个 UC,具体取决于单击的树节点。当用户单击不同的树节点时,我没有进行任何内存管理,所发生的情况是,无论需要什么 UC 都已加载到旧节点之上。我曾以为 C# 处理内存管理,但是我发现如果我连续单击我的一个树节点,单击离开,然后再次单击同一个树节点,每次加载 UC 时,内存使用量都会持续上升。点击离开并不会释放内存。这里没有非托管代码,但是在 UC 上的 Oracle 中发生了数据库访问,加载了带有记录的 DataGridView。每次单击此树节点时,我需要做什么才能使内存停止爬升?我正在使用 Process Explorer 来监控内存使用情况。在我停止点击之前,它的容量已超过 1 GB。这是加载右侧窗格的代码。谢谢。
private void LoadRightPane(TreeNode node)
{
splitPanelLeftRight.Panel2.Controls.Clear();
try
{
this.Cursor = Cursors.WaitCursor;
// Need to create user control on GUI thread
// But we still will load the various grids on the BW thread
UserControl uc = null;
IUap uap;
INodeTag nodeTag = (INodeTag)node.Tag;
bool result;
result = _uapList.TryGetValue(nodeTag.AssemblyTypeName, out uap);
if (result)
{
uc = uap.Create(node); // decides which user control to "new" (based on node info) and returns it
}
if (uc != null)
_bw.RunWorkerAsync(uc);
else
{
this.Cursor = Cursors.Default;
}
}
catch (Exception ex)
{
this.Cursor = Cursors.Default;
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
if (!(e.Argument is IUapUserControl))
throw new Exception("Exception: All user controls must implement the IUapUserControl interface.");
IUapUserControl uc = e.Argument as IUapUserControl;
uc.Populate(); // populates any info on UC
e.Result = uc;
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
// check for an exception first
if (e.Error != null)
{
return;
}
if (e.Result != null)
{
splitPanelLeftRight.Panel2.Controls.Add((UserControl)e.Result);
}
}
catch (Exception ex)
{
LoggingWrapper.Logger.LogException(ex);
}
finally
{
this.Cursor = Cursors.Default;
}
}