Adventures with threads
I was working, today, on a tool to visit all controls in a VB.Net form while emitting events for control visits. It worked fine as long as I set its property to not spawn independent threads, but it worked not so great when I did set this property.
I realized that because the controls and subcontrols were being visited "postorder", with all children of any form, group box, or other control with a nonempty collection of Controls being visited (by starting a thread using a new traversal instance) BEFORE visiting the parent, at all levels, I'd made an error.
The child visits on my test application were supported by an event handler which turned the control red, inserted a visit record, and restored its original colors.
I noticed that for all group boxes in a random set of created controls, the first member control of each group box would turn red, and stay red, while a separate thread would turn its parent red, restore its color, and proceed to the next control at its level!
Of course, when I looked at the code, I realized that while I'd properly LOCKED each control just before calling the visitEvent for the control, threads for child controls were STILL EXECUTING when it came time to (1) lock the Parent, (2) visit the Parent, and (3) unlock the Parent.
Whatever the specific effects of locking the parent control while a thread is banging away at one of its child controls, I realized they were Not Good.
I needed to wait, after firing threads for the kiddies, until all those threads were stopped, before locking and firing for the Parent.
But then I had a further epiphany of the good sort, where the flaws in your design directly imply something Much Better.
I realized that I was making a mistake to which I am prone because of my long experience, as a programmer.
You see, my first machine had NO operating system and I grew used to creating, for each applications, an infrastructure of support designed for that application alone.
Today, I have a tendency, at times, to overelaborate solutions with extras. I believe most of my "extras" are good but they don't help me spot truly simple solutions.
For example, Corey Haines was discussing how he would generalize the scanner in my book code...by implementing it as an abstract class with plugins for different languages. My solution MIGHT be to instead parse a lexx description of the new language!
I realized today that I was spending quite a lot of brain power MERELY on iterating and recursively TRAVERSING through the controls of a form...while this problem, of "iterating through a set of objects which may contain subsets" occurs all over, notably in file systems.
Therefore I am overhauling the code to be an abstract class.
In my consulting, especially in C#, I have seen a lot of abstract iterators which are then instantiated with the object type. They seemed to me then, and seem to me still, overkill and useless overlaying, for one knows how to write For loops...and the iterators I have seen work in one thread, strictly sequentially.
They don't at all address the fact that in perhaps 80% of For and even Do loops, the operations CAN be done in any order but ARE performed "from zero or one by one", thereby not exploiting any parallelism lying about the shop!
I realized that despite all the iterators I have seen, the REAL solution isn't iteration at all.
Iteration is a SPECIAL CASE of n-way tree traversal, and n-way trees occur heavily in object models, such as the Windows form!!
Therefore I am building Travis, a SIMPLE abstract class for traversal of n-way trees including trees with the poor taste to degenerate into arrays. The name is from the Clash's best album, Combat Rock:
HAS ANYONE PROPHESIED THESE PEOPLE? ONLY TRAVIS: COME IN TRAVIS.
ALL THE ANIMALS COME OUT AT NIGHT! QUEERS, FAIRIES, DOPERS, JUNKIES, SICK...VENAL! ONE OF THESE DAYS A REAL RAIN WILL COME AND WASH ALL THE TRASH OFFA THE STREETS! LISTEN YOU SCREWHEADS! HERE IS A MAN WHO COULD NOT TAKE IT ANYMORE, A MAN WHO STOOD UP AGAINST THE SCUM, THE FILTH...
Travis shall of course allow EITHER deterministic or nondeterministic traversal.
It shall expose a property for controlling deterministic visitation of elements: the deterministic order shall be either PREORDER or POSTORDER. In preorder, the Children is visited before the Parent. In postorder the Parent is served before the kids.
The terminology is taken from similar orders, but defined strictly for binary trees such that each Parent has 0..2 Children, and a third time applies to binary trees: in "inorder", child one is visited, the parent is visited, then child 2 is visited.
"Inorder" SEEMS to make no sense for n-way trees such as MS DOS directories and the Form model, unless you visited the parent after visiting n/2 children where n is the number of kids. This seems useless.
In general, I was amazed to learn of the reduction of n-way to binary trees in graduate school; any n-way tree can be automatically transformed into a binary tree simply by adding nodes.
But I was subsequently astonished to learn just how useless this fact is in my corner of the real world. My most common "tree" is a Collection with Collections as members, or something like the Microsoft Office objects, which are objects containing nested objects, and it MAKES NO SENSE to EVER expand these by adding nodes to make them "binary".
[Parenthetically, an object with subobjects or a Collection containing subcollections is mathematically a tree UNLESS it contains a reference, at level n, to the SAME object at a higher level, where it becomes a graph. You need to plan for this when writing code to walk through what you think is a graph but which can be a graph. I recently enhanced some software I'd originally written for an article in Visual Studio to display a VB-6 object as an engineering style outline, and gave it to a coworker. I took care of the possibility that a tree would be a graph by means of an auxiliary collection, searched using a hash technique based on the object name where available, and a simple cross reference in the output.]
In other words...as truly useful as a grad level in data structures is, and it is, you need then to unlearn the "reification" inherent in encountering abstractions in school merely to recognize REAL world objects that happen to instantiate some or all of their characteristics!
It might be thought, why the hell go to grad school. My answer is that unlearning the Platonism, of prizing the abstractions such as the binary tree, of considering them to be "above", to be "better than" some VB Collection, and learning the Aristotelean love (also, the love of St Thomas Aquinas) for earthly instantiations of "ideal objects" requires that you understand the Platonism.
Aristotle would not have thought the way he did without Plato.
A programmer without training in "trees" won't understand the structure of a VB form...and will write code to iterate through its Controls collection in a flat way. The code will "work" for the first version of the form, but then our boy adds a Group box with some controls.
Boom. The loop misses the controls in the Group box.
This is, I think, an example of the magic of linking theory and practice.
Theory so little informs practice, and practice theory, in American computing that when people embark on arcane projects (such as using threads), they preabandon rigor and theory and instead trust to a diffuse style-of-thinking "out of the box", "like a hacker", "like the end user". The result is almost always a mess...in multiprocessing, those charming programs with nonreproducible bugs.
Human resources flacks and other creatures LOVE lecturing programmers, in my experience, about "focus"...as if programming was not an art that forces the most extreme sort of "focus". Generally, what they mean is something sorta like business and the "needs" of the user.
This is all well and good. But it also DENIES that programming is anything like a body of knowledge which could be organized, as a profession.
At the same time, people outside the field express wonderment as to how, for example, a compiler works.
Only the computer science professors are in the final analysis true mentors for their lessons, in my experience, can be applied as long as one treats the application process itself, as did Dijkstra, with a certain secular reverence.
For example, I've read countless BUSINESS books about "business rules" without one ever addressing how one might actually even parse such a thing, much less evaluate a SET of rules for simple logical consistency. Indeed, much of the frustration people encounter with automated corporate and government bureaucracies might today be explained by the simple fact that their "business rules" form a contradictory or incomplete system in Godel's sense.
[And note that the suits leave the room, or fall on the floor laughing, as soon as I mention Godel's name, as if some sort of scientific tradition could not inform MIS practice...as if that might not be fairer, in the sense of more transparent, ultimately, to the real end user.]
[Indeed, and "let us not speak falsely now the hour is much too late", the utter meaningless of George Bush's sound-bytes, the way in which he confuses or mangles syntax and semantics, is no accident, for corporations and government entities have long relied on lack of precision.]
In my own struggles, I have found that adding both tools and approaches makes it even more important to retain the basics.
I am also less guilty these days, about making a deep change in direction such as described above, rather than (in the above example) persisting in making an overelabote tool MERELY to visit all controls.
"Hey Ed, doncha know it's been done before and if you go to such and such a site you can git free code?"
Why is it that when I was a kid, they say "it cannot be done", but now they say "it's been done?"
Seriously, I mistrust "free code" in part because I need to understand what I am doing and can write my own code, in many but by no means all instances, than "install" some "tool"...which requires me to install SQL server.


Recent comments
3 weeks 5 days ago
3 weeks 5 days ago
38 weeks 5 days ago
39 weeks 4 days ago
39 weeks 4 days ago
40 weeks 4 days ago
41 weeks 20 hours ago
41 weeks 21 hours ago
41 weeks 2 days ago
41 weeks 3 days ago