Bob, sorry for the delayed answer, but I've been rather busy all week...
>>I wanted to ask what was the cause (if you ever found it - it may be yet another analysis/paralysis situation), but from your solution it seems to be that buffering (i.e. TableUpdate()ing) actually employs some better techniques than simple Replace or Gather may do. Good thing to remember, may save our necks some day.
>The cause is unknown, but I do have a solution based on some testing. I built a test that was busy adding and recycling records as fast as I could. It caused no index corruption. I tried running 3 copies of it (3 exe's) on the same machine. No corruption. But with 10 copies running, I could always produce a corrupted index within 10 minutes.
>I then turned buffering on for the table I was working with, and threw in a tableupdate() after my REPLACE or INSERT INTO, and the corruption dissappeared. I then let it run for a weekend (54 hours and about 9 million insertions or recycles) and it worked.
Just rings a bell - and it may be my paranoia warning me. What if TableUpdate() is using a different record/index handling engine, which is more consistent and robust than plain old xBase one? Nobody said there's much wrong with the old one, yet cases like this show it. Nobody said we shouldn't use the old one, either, but still... they recommend the new one from VFP3. This just shows it's capable of doing some things the old one isn't.
>That's about it. The only interesting side note is that it was working so hard, that two of my processes came up with a windows error complaining about being unable to write to a file because it already existed. It used one of those random names (both processes named the same random file name). It wasn't me creating the files, so I must have been going fast enough for windows' "guaranteed unique" filenames system to bump into itself. When I clicked OK on each stoped process's error message, they started going again and ran to completion.
Another gotcha. Your unique names are unique within a process, but this shows they're not that unique on machine level. I'll start thinking of having each instance of the app creating things in its private temporary directory, and have defragmentation agent on by default :)