Skip to main content
 首页 » 编程设计

c#之不断添加和删除到 flowlayoutpanel winforms

2024年08月12日52小虾米

我有一个 c# win 表单应用程序,其中有一个 flowLayoutPanel

我需要每秒更新这个面板中的所有 child 。

这是我当前的代码,每 1 秒在系统计时器中调用一次:

   public void RefreshReceiversPage() 
    { 
        if (checkBox_enableReceivers.Checked) 
        { 
            var receivers = OutgoingReceiverManager.GetCopyOfActiveRecieverHolders(); 
 
            for (int i = 0; i < flowLayoutPanel_receivers.Controls.Count; i++) 
            { 
                var tmp = flowLayoutPanel_receivers.Controls[i]; 
                flowLayoutPanel_receivers.Controls[i].Dispose(); 
                tmp.Dispose(); 
            } 
            flowLayoutPanel_receivers.Controls.Clear(); 
 
            foreach (var item in receivers.ToList()) 
            { 
                var tmpUc = new ucReceiverItem(item); 
                if (flowLayoutPanel_receivers != null) 
                { 
                    try 
                    { 
                        flowLayoutPanel_receivers.Controls.Add(tmpUc); 
                    } 
                    catch 
                    { 
                    } 
                } 
            } 
            receivers = null; 
        }             
    } 

现在这段代码完美运行了大约 2 分钟,然后突然间我开始收到 error creating window handle 因此我在上面的代码中 try catch 的原因。

但发生这种情况后, Pane View 变得很奇怪,我无法在不重新启动程序的情况下恢复它。

我到处搜索,似乎找不到有关抛出的异常的任何信息?

我能想到的是,我可能没有正确处理对象,并且它在某个地方耗尽了内存?

有没有人有任何建议或解决方案?

编辑:

这里是 UCRecieverItem:

public partial class ucReceiverItem : UserControl 
{ 
    public ucReceiverItem(ReceiverHolder item) 
    { 
        InitializeComponent(); 
        ConstructItem(item); 
        item = null; 
    } 
 
    private void ConstructItem(ReceiverHolder item) 
    { 
        label_name.Text = item.ReceiverDb.Name; 
        label_numberOfConnections.Text = item.ReceiverOutgoingConnectionManager.GetNumberOfConnections().ToString(); 
        label_mrFilters.Text = item.ReceiverDb.MrFilters; 
        label_multipleConnections.Text = item.ReceiverDb.MultipleConnections.ToString(); 
        // 
        int count = item.GetActiveBufferCount(); 
        int size = item.GetActiveBufferSize(); 
        // 
        label_bufferCount.Text = count + @" / " + size; 
        progressBar_buffer.Maximum = size; 
        progressBar_buffer.Minimum = 0; 
        progressBar_buffer.Value = count; 
    } 
} 

请您参考如下方法:

这段代码有问题:

for (int i = 0; i < flowLayoutPanel_receivers.Controls.Count; i++) 
{ 
  var tmp = flowLayoutPanel_receivers.Controls[i]; 
  flowLayoutPanel_receivers.Controls[i].Dispose(); 
  tmp.Dispose(); 
} 
flowLayoutPanel_receivers.Controls.Clear(); 

它仅处理容器中的一半 控件。另一半被 Controls.Clear(); 调用删除,但这些控件没有被释放——所以它们仍然存在并且正在耗尽内存。

每秒钟都这样做会使问题复杂化:这可能需要很多控制。

立即的解决方法是妥善处理控件:

while (flowLayoutPanel_receivers.Controls.Count > 0) { 
  flowLayoutPanel_receivers.Controls[0].Dispose(); 
} 

在那之后,我会质疑是否有必要每秒都这样做——这对用户来说似乎是一个恶劣的工作环境。