We're all shooting in the dark here because you haven't provided all the relevant code. That said, the information you have provided has a lot of problems, and I can offer advice to help you solve it.
Debugging 101
Run your code through the IDE. When you get your exception, the debugger stops at the line that caused the exception.
This is usually the most important step in figuring out what went wrong. You have access to this information. Run your program and carefully look at the line that raised the error. You might be able to already figure what caused the error. If not, a other basic techniques can be applied to get more information:
- Get values of objects and variables on the error line and other close lines. You can hover your mouse cursor to get tool-tips, or press Ctrl + F7.
- You can examine the call stack of lines leading to the one that caused the error by double-clicking the previous line in the call-stack.
- Put a breakpoint on the line before the error and re-run the app. The debugger will stop on that line and give you a chance to check values as explained earlier, but before the error happens.
Asking for help 101
Getting help from people is much more effective when you give them all the relevant information. For a start, the line of code where the access violation occurs would be extremely useful.... Tell us!
Give us real code.
Saying "I tried to do something like this" is not particularly useful. Please copy and paste exactly what you tried. If your code is different, your mistake might no longer be there.
Access Violations
You get an access violation in the following situations:
- You forgot to create the object you want to use or didn't assign it to the appropriate variable.
- You created the object but
Destroy
ed or Free
d it already before trying to use it again.
- You changed the variable that was referencing the object.
- You performed a 'hard-cast' (or unchecked typecast) from one type to an incompatible type.
- The above are the basics. There some variations, and a few special edge cases, but these account for the vast majority of mistakes.
So using the above, that's what you need to check. If you had copy-pasted more of your code, we might be able to see what you did wrong.
NOTE: One shot-in-the-dark possibility is that you are destroying your string list in the wrong place. And perhaps the memo works because as a component dropped on the form, you're not trying to destroy it.
Stack overflow
Let's examine what happens in your OnChange event when for example a string is added:
- The event fires.
Text
is not empty.
- So you call
ProcessCommands
- You then call
Clear
- The the end of
Clear
, Changed
is called again.
- Which fires your event again.
- This time
Text
is empty, so you won't call ProcessCommands
- But you do try to
Clear
the string list again...
- This could go on forever; well at least until the call-stack runs out of space and you get a stack-overflow error.
Saved by the bell
The only reason you don't get a stack overflow is because Clear
doesn't do anything if the string list is empty:
procedure TStringList.Clear;
begin
if FCount <> 0 then //You're lucky these 2 lines stop your stack-overflow
begin
...
FCount := 0; //You're lucky these 2 lines stop your stack-overflow
SetCapacity(0);
Changed;
end;
end;
I suggest you rethink how to solve you problem because code that leads to unintentional recursion is going to make your life difficult.
Working with threads
You really need to get a handle on the basics of programming before trying to work with threads. Multi-threaded programming throws in a huge amount of complexity.
I can already see a huge possibility of one potential mistake. (Though it depends what you're doing inside ProcessCommands
.)
- You modify your string list in the context of a thread.
- This means your
OnChange
event handler also fires in the context of the thread. (The fact it's implemented on the form is irrelevant.)
- If your
ProcessCommands
method does anything that requires it to operate on the main thread, you're going to encounter problems.
As a final consideration, I've noted quite a few beginner programmers completely miss the point that code starting a thread can finish before the thread does. E.g. (Going back to the topic on Access Violations.): If you're destroying your string list soon after creating your thread, your thread could suddenly throw an access violation when the object it had earlier is suddenly gone.