Board index » cppbuilder » How can I interrupt TStringList->CustomSort periodically?

How can I interrupt TStringList->CustomSort periodically?


2005-06-13 04:19:28 PM
cppbuilder23
I have a program that builds a very large TStringList and
then calls CustomSort, which can run for 5-10 minutes.
I'd like to give the user some visual indication that the
program is still alive and well (he can't do anything else
in the program until the sort finishes).
I tried using a TTimer with an interval of 30 seconds, with
an update of the status bar whenever the timer fires. But
the OnTimer event never gets executed.
What am I missing? The relevant pieces of code are pasted here.
//--------------------------------------------------------------------
int __fastcall CustomCompare(TStringList* SL, int Idx1, int Idx2)
{
Compares += 1;
int R = strcmp(SL->Strings[Idx1].c_str(), SL->Strings[Idx2].c_str());
if (!R)
{
int Line1 = reinterpret_cast<int>(SL->Objects[Idx1]);
int Line2 = reinterpret_cast<int>(SL->Objects[Idx2]);
R = (Line1>Line2) - (Line1 < Line2);
}
return R;
}
//---------------------------------------------------------
void __fastcall TForm1::OnSortTimer(TObject *Sender)
{
Elapsed = Elapsed + (SortTimer->Interval / 1000);
String Info = "After " + IntToStr(Elapsed) + " seconds, "
+ IntToStr(Compares) + " comparisons";
StatusBar->SimpleText = Info;
Application->ProcessMessages();
}
//---------------------------------------------------------
// the code in question happens below .... timer doesn't fire
StatusBar->SimpleText = "Now sorting word list.";
Application->ProcessMessages();
Elapsed = 0; // Elapsed and Compares
Compares = 0; // have form scope.
SortTimer->Enabled = true;
SortTimer->Interval = 30000; // 30 seconds
Words->CustomSort(CustomCompare);
SortTimer->Enabled = false;
StatusBar->SimpleText = "Word list sorted.";
Application->ProcessMessages();
//---------------------------------------------------------
Thanks for reading.
Adrian Carter
 
 

Re:How can I interrupt TStringList->CustomSort periodically?

Adrian Carter wrote:
Quote
What am I missing? The relevant pieces of code are pasted here.
Do away with TTimer as it has no change to trigger
while CustomSort runs.
Place the code for the info in the compare function.
int starttickcount; // global
int Compares; // global
Quote
int __fastcall CustomCompare(TStringList* SL, int Idx1, int Idx2)
{
Compares += 1;
int R = strcmp(SL->Strings[Idx1].c_str(), SL->Strings[Idx2].c_str());
if (!R)
{
int Line1 = reinterpret_cast<int>(SL->Objects[Idx1]);
int Line2 = reinterpret_cast<int>(SL->Objects[Idx2]);
R = (Line1>Line2) - (Line1 < Line2);
}
int elapsedtime = GetTickCount() - starttickcount;
String Info = "After " + IntToStr(elapsedtime /1000) + " seconds, "
+ IntToStr(Compares) + " comparisons";
StatusBar->SimpleText = Info;
StatusBar->Update();
Quote
return R;
}
starttickcount = GetTickCount();
Compares = 0;
Words->CustomSort(CustomCompare);
Hans.
 

Re:How can I interrupt TStringList->CustomSort periodically?

Interesting. I would have predicted the program would take quite a big
execution time
hit with this approach. But no, if I only test once every 1000 compares, and
then update
the statusbar at least 40 secs after the last update, it adds less than 1%.
Thanks for the suggestion.
Adrian
"Hans Galema" < XXXX@XXXXX.COM >wrote in message
Quote
Adrian Carter wrote:

>What am I missing? The relevant pieces of code are pasted here.

Do away with TTimer as it has no change to trigger
while CustomSort runs.

Place the code for the info in the compare function.

int starttickcount; // global
int Compares; // global

>int __fastcall CustomCompare(TStringList* SL, int Idx1, int Idx2)
>{
>Compares += 1;
>int R = strcmp(SL->Strings[Idx1].c_str(), SL->Strings[Idx2].c_str());
>if (!R)
>{
>int Line1 = reinterpret_cast<int>(SL->Objects[Idx1]);
>int Line2 = reinterpret_cast<int>(SL->Objects[Idx2]);
>R = (Line1>Line2) - (Line1 < Line2);
>}

int elapsedtime = GetTickCount() - starttickcount;

String Info = "After " + IntToStr(elapsedtime /1000) + " seconds, "
+ IntToStr(Compares) + " comparisons";

StatusBar->SimpleText = Info;
StatusBar->Update();

>return R;
>}



starttickcount = GetTickCount();

Compares = 0;

Words->CustomSort(CustomCompare);

Hans.
 

{smallsort}

Re:How can I interrupt TStringList->CustomSort periodically?

"Hans Galema" < XXXX@XXXXX.COM >wrote in message
Quote
Do away with TTimer as it has no change to trigger
while CustomSort runs.
It will if CustomCompare() calls Application->ProcessMessages()
periodically.
Quote
int elapsedtime = GetTickCount() - starttickcount;
You are not taking into account that the value GetTickCount() wraps back to
0 every 49.7 days. Also, 'int' is not a good data type to use with
GetTickCount(). Use 'DWORD' instead:
DWORD StartTickCount;
int __fastcall CustomCompare(TStringList* SL, int Idx1, int Idx2)
{
//...
DWORD ElapsedTime;
DWORD CurrentTickCount = GetTickCount();
if( CurrentTickCount>= StartTickCount )
ElapsedTime = (CurrentTickCount - StartTickCount);
else
ElapsedTime = ((0xFFFFFFFF - StartTickCount) +
CurrentTickCount);
//...
}
{
StartTickCount = GetTickCount();
Words->CustomSort(CustomCompare);
}
Gambit