I’m working on a DB Lookup Combo with filter, sorting and most important: instance search (like winamp).
So, I figured I’d use a TClientDataSet as a proxy dataset for my combo and just descend from TDBLookupComboBox
All nice and dandy until the part where I have to respond to changes in the original dataset and update my proxy one. As always I did it like
dataset.disableControls; try dataset.first; while not dataset.eof do blabla finally datasert.enableControls; end;
The component was integrated into a financial application and for some reason I got the freeze, but only for a few seconds. For the life of me I couldn’t figure out what it was wrong, especially because from about 10 similar adotables and about the same number of forms, similar in construction and components, it only happened with one and only one. MadExcept by itself was not useful as setting the freeze timeout to 2 second it didn’t fire. Then I remembered madTraceProcess.exe and that did it: it showed the issue being in my component. A few breakpoints in the right spot (trial and error) got me seeing the recursion happening on the dataset.enableControls line. A few more minutes of debugging proved that the issue was caused by that usage as I was doing it in the DataLink.DataSetChanged method which is called when the dataset “changes”. But if you look through the code in DB.pas you’ll notice that the datasetChanged is called in a lot more other situations, but most notably in EnableControls.
Long story short, this is probably the “best” infinite recursion I’ve ever seen till now. and it was caused because my assumption that datasetChanged is called when the dataset changes. Wrong, it is called in EnableControls as well.