Having a problem I can’t seem to put my finger on. I am trying to gather strings (random code with letters and numbers) from a function call and place into my TStringList variable. Relevant code is below.
If I run a test, the strings repeat for a given amount of time then a new one is produced. If I introduce a sleep(xx) or showmessage command to happen after each time a code is produced (see ‘edits’ below) it copies/returns to memo fine and everything looks fine. If I remove the ‘delay’ I get repeats from function again.
The part of function to add to TStringList:
..
AddToMemo:=TStringList.Create;
AddToMemo.Clear;
AddToMemo.Sorted:=False;
for loop := 1 to totalamount do
begin
sResult:=MakeCode(charspercode, cbUpperLowerCase, cbAvoidChars, customchars);
Sleep(50);
// (or):
//ShowMessage(sResult);
// ^ If I leave a Sleep or ShowMessage in, I can see sResult just fine and
// program works fine - results in memo are correct as well. If I remove
// it, I get repeated entries.
AddToMemo.add(sResult+IntToStr(loop));
// If I remove "sResult+" from AddToMemo.add the ".add"
// works - shows loop numbers in my updated memo
// If left in, I see one code (1st one produced) and no
// appended number at all in Memo produced.
end;
Result:=AddToMemo;
end;
Edit: As I mention below if I leave a ShowMessage or Sleep(xx) call in to pause between .add’s, it works fine. If I remove it, I get a bunch of duplicate entries in final tmemo.
Edit: MakeCode is a function to return a single random string of chars+numbers (A..Z a..z 0..9). It works fine on it’s own.
(Edit for Answer 2)
No exceptions showed up.
So if I do not include sleep() it may generate 500 strings but they are all repeats; after a given amount of time it does change. The amount of repeats from the function call decreases as I increase sleep command. At around Sleep(40); it shows up correctly from function. But of course this is time consuming and unacceptable.
The ‘guts’ of MakeCode()
function MakeCode(CharsPerCode: Integer; bULCase, bAvoidChars: Boolean; sCChars: String): String;
var
i: integer;
s: string;
begin
//(misc stuff here)
begin
randomize;
s[0]:=chr(CharsPerCode);
for i:=1 to CharsPerCode do
repeat
s[i]:=chr(random(128));
until
(s[i] in ['A'..'Z','a'..'z','0'..'9'])
end;
Result:=s;
end;
This is a behavior of
Randomize. The random number generator is initialized by a calculation on the system clock. If you call it in each iteration in a quick loop, it is initialized with the same seed. That’s why aSleep(50)is changing the outcome. Call randomize for once, for instance, before starting to populate the string list.The below quote is from the Delphi documentation: