I have two controls on my form: a listbox with a list of workers and a panel which acts as a container for showing the details (cards) about their work. When a user clicks on the worker s name, I display cards on the panel. A card is a usercontrol with some fairly simple UI (2 groupboxes, 3 textboxes and several labels) and simple logic (setting forecolor of labels).
The cards are created in runtime. Previous cards are removed from the panel and the new ones get added - the number of cards per worker is 1 to 4. It gets interesting here.
Everything works fine until approx. the fifth click on the workers. It seems that GC kicks in and it takes about two seconds (0.3s x number of previously removed cards) for the old cards (previously removed) to get disposed and new ones shown. If moving between workers works great before, it gets painfully slow at that point.
After some exploring I ve located the problem to lay in Dispose
method of my usedcontrol. Call base.Dispose()
takes about 0.3s.
以下是我的代码:
private void ShowCards(List<Work> workItems) {
var y = 5;
panelControl1.SuspendLayout();
panelControl1.Controls.Clear();
foreach (var work in workItems) {
var card = new Components.WorkDisplayControl(work);
card.Top = y;
card.Left = 10;
y += card.Height + 5;
panelControl1.Controls.Add(card);
}
panelControl1.ResumeLayout(true);
Application.DoEvents();
}
到目前为止,我曾尝试过:
- hiding cards instead of disposing - it works faster when moving between workers, but the penalty is paid when closing the form
- hiding the cards and have a separate thread which disposes them - no change
- test with adding 10 cards and disposing them immediately - slow
- test with adding 10 cards and disposing them immediately in the constructor - FAST!
- replaced DevExpress controls with “normal” – no change
- manually disposing old cards instead of removing them when changing worker - every move between workers gets slower:
for (var ix = panelControl1.Controls.Count - 1; ix >= 0; --ix) { panelControl1.Controls[ix].Dispose();}
- profiling it - that s how I ve found the problem in
Dispose
. I can trace it down toControl.DestroyHandle
- calling
Controls.Clear()
inDispose
method of my control - super strange behaviour and exceptions - removed all of the controls from my usercontrol - a little bit faster, but still slow
- hiding
panelControl1
when removing and adding cards - no change - turned background GC off - no change
- adding cards with
AddRange
由于同一功能在从构建器中调用时快速运作,我确信原因一定是在(控制)把手的某处。
我只是找不到这种奇怪行为的原因 我非常感激...
更新: 在研究GC与控制之间的连接时。 丢弃我发现 < a href=> https:// stackoverflow. com/ a/ 9432317/820604> 这个极好的答复 a>