git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.jvcl@12 7f62d464-2af8-f54e-996c-e91b33f51cbe
674 lines
21 KiB
C++
674 lines
21 KiB
C++
/******************************************************************
|
|
|
|
JEDI-VCL Demo
|
|
|
|
Copyright (C) 2002 Project JEDI
|
|
|
|
Original author:
|
|
|
|
Contributor(s):
|
|
korecek: translation from Delphi to BCB
|
|
|
|
You may retrieve the latest version of this file at the JEDI-JVCL
|
|
home page, located at http://jvcl.sourceforge.net
|
|
|
|
The contents of this file are used with permission, subject to
|
|
the Mozilla Public License Version 1.1 (the "License"); you may
|
|
not use this file except in compliance with the License. You may
|
|
obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/MPL-1_1Final.html
|
|
|
|
Software distributed under the License is distributed on an
|
|
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
implied. See the License for the specific language governing
|
|
rights and limitations under the License.
|
|
|
|
******************************************************************/
|
|
// $Id: fThread.cpp 11331 2007-06-17 16:38:39Z jfudickar $
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include <vcl.h>
|
|
#pragma hdrstop
|
|
#include <stdlib.h>
|
|
|
|
//#include "D:\Program Files\Borland\CBuilder5\User Components\JVCL\run\JvThread.hpp"
|
|
//#include "JvThread.hpp"
|
|
#include "fThread.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
#pragma link "JvComponent"
|
|
#pragma link "JvThread"
|
|
#pragma link "JvThreadDialog"
|
|
#pragma link "JvComponentBase"
|
|
#pragma link "JvExMask"
|
|
#pragma link "JvSpin"
|
|
#pragma resource "*.dfm"
|
|
TForm1 *Form1;
|
|
//---------------------------------------------------------------------------
|
|
int LifeTime=0;
|
|
bool SuspendRandomThread=false;
|
|
bool RaiseExceptInThread=false;
|
|
//---------------------------------------------------------------------------
|
|
typedef struct SJobData
|
|
{
|
|
int Dummy[10];
|
|
} SJobData;
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TForm1::TForm1(TComponent* Owner)
|
|
: TForm(Owner)
|
|
{
|
|
randomize();
|
|
|
|
cbExclusive1->Checked=JvThread1->Exclusive;
|
|
cbExclusive2->Checked=JvThread2->Exclusive;
|
|
|
|
seMaxCount1->AsInteger=JvThread1->MaxCount;
|
|
seMaxCount2->AsInteger=JvThread2->MaxCount;
|
|
|
|
cbDeferredExecution1->Checked=!JvThread1->RunOnCreate;
|
|
cbDeferredExecution2->Checked=!JvThread2->RunOnCreate;
|
|
|
|
cbDeferredDeletion1->Checked=!JvThread1->FreeOnTerminate;
|
|
cbDeferredDeletion2->Checked=!JvThread2->FreeOnTerminate;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThread1Execute(TObject *Sender, Pointer Params)
|
|
{
|
|
// old: TJvThread* Container=dynamic_cast<TJvThread*>(Sender);
|
|
|
|
TJvBaseThread* ThisThread=dynamic_cast<TJvBaseThread*>(Sender);
|
|
if(ThisThread==NULL) // for testing only
|
|
throw Exception("Execution error: 'Sender' is not TJvBaseThread object");
|
|
|
|
if(JvThread1->Terminated) // flag 'Terminated' for current thread; slower then direct ThisThread->Terminated
|
|
{ // terminated before resume
|
|
JvThread1->ReturnValue=-1; // for current thread; slower then direct ThisThread->ReturnValue
|
|
exit;
|
|
}
|
|
|
|
int i, j, k;
|
|
bool FL_Break=false;
|
|
|
|
JvThread1->ReturnValue=0; // for current thread; slower then direct ThisThread->ReturnValue
|
|
|
|
//Do the job here
|
|
k = 0;
|
|
for(i=0; i<1000 && !FL_Break; ++i)
|
|
{
|
|
for(j=0; j<10; ++j)
|
|
{
|
|
++k;
|
|
// I included here ::Sleep(0) unlike the original Delphi code to
|
|
// allow the other threads to process as well. (c)VK
|
|
::Sleep(0);
|
|
//To use global variable/objects, you have to synchronize (to avoid conflicts)
|
|
Form1->ThreadID1 = ThisThread->ThreadID;
|
|
Form1->Value1 = k;
|
|
JvThread1->Synchronize(Form1->Stats1); // slower then direct ThisThread->Synchronize(Form1->Stats1)
|
|
|
|
if(SuspendRandomThread)
|
|
{
|
|
SuspendRandomThread=false;
|
|
JvThread1->Suspend(); // current thread (i.e. itself)
|
|
}
|
|
|
|
if(RaiseExceptInThread)
|
|
{
|
|
RaiseExceptInThread=false;
|
|
JvThread1->ReturnValue=666; // for current thread; slower then direct ThisThread->ReturnValue
|
|
throw Exception("Exception in Job1, ThreadID="+IntToHex((int)ThisThread->ThreadID, 8));
|
|
}
|
|
|
|
if(JvThread1->Terminated) // flag 'Terminated' for current thread; slower then direct ThisThread->Terminated
|
|
{
|
|
FL_Break = true;
|
|
JvThread1->ReturnValue=1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThread2Execute(TObject *Sender, Pointer Params)
|
|
{
|
|
// old: TJvThread* Container=dynamic_cast<TJvThread*>(Sender);
|
|
|
|
TJvBaseThread* ThisThread=dynamic_cast<TJvBaseThread*>(Sender);
|
|
if(ThisThread==NULL) // for testing only
|
|
throw Exception("Execution error: 'Sender' is not TJvBaseThread object");
|
|
|
|
if(ThisThread->Terminated)
|
|
{
|
|
ThisThread->ReturnValue=-1; // terminated before resume
|
|
return;
|
|
}
|
|
|
|
if(LifeTime)
|
|
{
|
|
// Sleep(LifeTime);
|
|
int t=GetTickCount();
|
|
while(GetTickCount()-t<LifeTime);
|
|
|
|
ThisThread->ReturnValue=555;
|
|
return;
|
|
}
|
|
|
|
SJobData* Data=reinterpret_cast<SJobData*>(ThisThread->Params); // Data==Params
|
|
|
|
TJvThread* Container=dynamic_cast<TJvThread*>(ThisThread->Container);
|
|
if(Container==NULL) // for testing only
|
|
throw Exception("Execution error: container is not TJvThread component");
|
|
|
|
int i, j, k=0;
|
|
//Do the job here
|
|
for(i=0; i<1000 && !ThisThread->Terminated; ++i)
|
|
{
|
|
for(j=0; j<10 && !ThisThread->Terminated; ++j)
|
|
{
|
|
k+=5; //This is the only difference with the other thread
|
|
::Sleep(Data->Dummy[1]);
|
|
//To use global variable/objects, you have to synchronize (to avoid conflicts)
|
|
Form1->ThreadID2 = ThisThread->ThreadID;
|
|
Form1->Value2=k;
|
|
ThisThread->Synchronize(Form1->Stats2);
|
|
// or Container->Synchronize(Form1->Stats2); // slower then direct ThisThread->Synchronize
|
|
|
|
if(SuspendRandomThread)
|
|
{
|
|
SuspendRandomThread=false;
|
|
JvThread2->Suspend(); // current thread (i.e. itself)
|
|
}
|
|
|
|
if(RaiseExceptInThread)
|
|
{
|
|
RaiseExceptInThread=false;
|
|
ThisThread->ReturnValue=666;
|
|
throw Exception("Exception in Job2, ThreadID="+IntToHex((int)ThisThread->ThreadID, 8));
|
|
}
|
|
}
|
|
}
|
|
|
|
if(ThisThread->Terminated) ThisThread->ReturnValue=1;
|
|
else ThisThread->ReturnValue=0;
|
|
|
|
if(Data->Dummy[0])
|
|
{ // Show sample msg before exit
|
|
AnsiString s;
|
|
if(ThisThread->Terminated) s="Job2: Terminated";
|
|
else s="Job2: Normal finish";
|
|
ThisThread->SynchMessageDlg(s+": ID=0x"+IntToHex((int)ThisThread->ThreadID, 8), mtInformation, TMsgDlgButtons()<<mbOK, 0);
|
|
// or Container->SynchMessageDlg(s+": ID=0x"+IntToHex((int)ThisThread->ThreadID, 8), mtInformation, TMsgDlgButtons()<<mbOK, 0);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::Stats1(void)
|
|
{
|
|
lbStats1->Caption = "ID:"+IntToHex(ThreadID1, 8)+ " V:"+IntToStr(Value1);
|
|
}
|
|
|
|
void __fastcall TForm1::Stats2(void)
|
|
{
|
|
lbStats2->Caption = "ID:"+IntToHex(ThreadID2, 8)+ " V:"+IntToStr(Value2);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnStartJob1Click(TObject *Sender)
|
|
{
|
|
JvThread1->ThreadDialog = NULL;
|
|
TJvBaseThread* t=JvThread1->Execute(NULL);
|
|
if(t)
|
|
{
|
|
int id=t->ThreadID;
|
|
Memo->Lines->Add("Job1 started: "+IntToHex(id, 8));
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnStartJob1SimpleDlgClick(TObject *Sender)
|
|
{
|
|
JvThread1->ThreadDialog = JvThreadSimpleDialog1;
|
|
TJvBaseThread* t=JvThread1->Execute(NULL);
|
|
if(t)
|
|
{
|
|
int id=t->ThreadID;
|
|
Memo->Lines->Add("Job1 with Simple Dlg started: "+IntToHex(id, 8));
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnStartJob2Click(TObject *Sender)
|
|
{
|
|
JvThread2->ThreadDialog = NULL;
|
|
SJobData* Data=new SJobData;
|
|
Data->Dummy[0]=cbShowMsgBeforeExit2->Checked;
|
|
Data->Dummy[1]=rand()%10;
|
|
TJvBaseThread* t=JvThread2->Execute(Data);
|
|
if(t)
|
|
{
|
|
int id=t->ThreadID;
|
|
Memo->Lines->Add("Job2 started: "+IntToHex(id, 8));
|
|
}
|
|
else
|
|
delete Data; // thread was not started
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnStartJob2AnimatedDlgClick(TObject *Sender)
|
|
{
|
|
JvThread2->ThreadDialog = JvThreadAnimateDialog1;
|
|
SJobData* Data=new SJobData;
|
|
Data->Dummy[0]=cbShowMsgBeforeExit2->Checked;
|
|
Data->Dummy[1]=rand()%10;
|
|
TJvBaseThread* t=JvThread2->Execute(Data);
|
|
if(t)
|
|
{
|
|
int id=t->ThreadID;
|
|
Memo->Lines->Add("Job2 with Animated Dlg started: "+IntToHex(id, 8));
|
|
}
|
|
else
|
|
delete Data; // thread was not started
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbExclusive1Click(TObject *Sender)
|
|
{
|
|
JvThread1->Exclusive=cbExclusive1->Checked;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbExclusive2Click(TObject *Sender)
|
|
{
|
|
JvThread2->Exclusive=cbExclusive2->Checked;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbDeferredExecution1Click(TObject *Sender)
|
|
{
|
|
JvThread1->RunOnCreate=!cbDeferredExecution1->Checked;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbDeferredExecution2Click(TObject *Sender)
|
|
{
|
|
JvThread2->RunOnCreate=!cbDeferredExecution2->Checked;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbDeferredDeletion1Click(TObject *Sender)
|
|
{
|
|
JvThread1->FreeOnTerminate=!cbDeferredDeletion1->Checked;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbDeferredDeletion2Click(TObject *Sender)
|
|
{
|
|
JvThread2->FreeOnTerminate=!cbDeferredDeletion2->Checked;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::seMaxCount1Change(TObject *Sender)
|
|
{
|
|
JvThread1->MaxCount=seMaxCount1->AsInteger;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::seMaxCount2Change(TObject *Sender)
|
|
{
|
|
JvThread2->MaxCount=seMaxCount2->AsInteger;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbPriority1Change(TObject *Sender)
|
|
{
|
|
int p=cbPriority1->ItemIndex;
|
|
if(p>=0)
|
|
{
|
|
int old=JvThread1->Priority;
|
|
JvThread1->SetPriority((TThreadPriority)p); // all threads
|
|
if(p>old) Memo->Lines->Add("Job1 priority boosted");
|
|
if(p<old) Memo->Lines->Add("Job1 priority reduced");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::cbPriority2Change(TObject *Sender)
|
|
{
|
|
int p=cbPriority2->ItemIndex;
|
|
if(p>=0)
|
|
{
|
|
int old=JvThread2->Priority;
|
|
JvThread2->SetPriority((TThreadPriority)p); // all threads
|
|
if(p>old) Memo->Lines->Add("Job2 priority boosted");
|
|
if(p<old) Memo->Lines->Add("Job2 priority reduced");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnSuspendAll1Click(TObject *Sender)
|
|
{
|
|
cbAutoStart1->Checked=false;
|
|
JvThread1->Suspend(); // all threads
|
|
Memo->Lines->Add("Job1 suspended");
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnSuspendAll2Click(TObject *Sender)
|
|
{
|
|
cbAutoStart2->Checked=false;
|
|
JvThread2->Suspend(); // all threads
|
|
Memo->Lines->Add("Job2 suspended");
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnResumeAll1Click(TObject *Sender)
|
|
{
|
|
JvThread1->Resume(); // all threads
|
|
Memo->Lines->Add("Job1 resumed");
|
|
cbAutoStart1->Enabled=true;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnResumeAll2Click(TObject *Sender)
|
|
{
|
|
JvThread2->Resume(); // all threads
|
|
Memo->Lines->Add("Job2 resumed");
|
|
cbAutoStart2->Enabled=true;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnTerminate1Click(TObject *Sender)
|
|
{
|
|
cbAutoStart1->Checked=false;
|
|
JvThread1->Terminate();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnTerminate2Click(TObject *Sender)
|
|
{
|
|
cbAutoStart2->Checked=false;
|
|
JvThread2->Terminate();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
|
|
{
|
|
Memo->Lines->Add("Application shutdown");
|
|
|
|
cbAutoStart1->Checked=false;
|
|
cbAutoStart2->Checked=false;
|
|
|
|
JvThread1->Terminate();
|
|
JvThread2->Terminate();
|
|
|
|
Memo->Lines->Add("Job1: waiting for completion ...");
|
|
JvThread1->WaitFor();
|
|
Memo->Lines->Add("Done");
|
|
|
|
Memo->Lines->Add("Job2: waiting for completion ...");
|
|
JvThread2->WaitFor();
|
|
Memo->Lines->Add("Done");
|
|
|
|
if(JvThread1->Count)
|
|
{
|
|
Memo->Lines->Add("Job1: removing zombies ...");
|
|
JvThread1->RemoveZombie();
|
|
Memo->Lines->Add("Done");
|
|
}
|
|
|
|
if(JvThread2->Count)
|
|
{
|
|
Memo->Lines->Add("Job2: removing zombies ...");
|
|
JvThread2->RemoveZombie();
|
|
Memo->Lines->Add("Done");
|
|
}
|
|
|
|
Memo->Lines->Add("Finished");
|
|
::Sleep(2000);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThreadBegin(TObject *Sender)
|
|
{
|
|
if(rbExOnBegin->Checked)
|
|
{
|
|
cbAutoStart1->Checked=false;
|
|
cbAutoStart2->Checked=false;
|
|
throw Exception("OnBegin");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThreadBeforeResume(TObject *Sender)
|
|
{
|
|
if(rbExOnBeforeResume->Checked)
|
|
throw Exception("OnBeforeResume");
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThread1Finish(TObject *Sender)
|
|
{
|
|
TJvBaseThread* t=dynamic_cast<TJvBaseThread*>(Sender);
|
|
if(t)
|
|
{
|
|
int id=t->ThreadID;
|
|
int rv=t->ReturnValue;
|
|
TJvThread* Container=dynamic_cast<TJvThread*>(t->Container);
|
|
|
|
Memo->Lines->Add("Job1 finished: "+IntToHex(id, 8)+" result: "+IntToStr(rv));
|
|
|
|
if(rbExOnFinish->Checked)
|
|
{
|
|
cbAutoStart2->Checked=false; // for preventing endless exception generation
|
|
throw Exception("OnFinish");
|
|
}
|
|
}
|
|
else // for testing only
|
|
Memo->Lines->Add("Job1 finished: unknown object 'Sender'");
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThread2Finish(TObject *Sender)
|
|
{
|
|
TJvBaseThread* t=dynamic_cast<TJvBaseThread*>(Sender);
|
|
if(t)
|
|
{
|
|
int id=t->ThreadID;
|
|
int rv=t->ReturnValue;
|
|
TJvThread* Container=dynamic_cast<TJvThread*>(t->Container);
|
|
|
|
Memo->Lines->Add("Job2 finished: "+IntToHex(id, 8)+" result: "+IntToStr(rv));
|
|
SJobData* data=(SJobData*)t->Params;
|
|
delete data;
|
|
|
|
if(rbExOnFinish->Checked)
|
|
{
|
|
cbAutoStart2->Checked=false; // for preventing endless exception generation
|
|
throw Exception("OnFinish");
|
|
}
|
|
}
|
|
else // for testing only
|
|
Memo->Lines->Add("Job2 finished: unknown object 'Sender'");
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThread1FinishAll(TObject *Sender)
|
|
{
|
|
TJvThread* Container=dynamic_cast<TJvThread*>(Sender);
|
|
Memo->Lines->Add("Job1 finished all");
|
|
if(rbExOnFinishAll->Checked)
|
|
{
|
|
cbAutoStart1->Checked=false; // for preventing endless exception generation
|
|
throw Exception("OnFinishAll");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::JvThread2FinishAll(TObject *Sender)
|
|
{
|
|
TJvThread* Container=dynamic_cast<TJvThread*>(Sender);
|
|
Memo->Lines->Add("Job2 finished all");
|
|
if(rbExOnFinishAll->Checked)
|
|
{
|
|
cbAutoStart2->Checked=false; // for preventing endless exception generation
|
|
throw Exception("OnFinishAll");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::MemoDblClick(TObject *Sender)
|
|
{
|
|
Memo->Clear();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::tmrStatusTimer(TObject *Sender)
|
|
{
|
|
lbCount1->Caption="Job1 count: "+IntToStr(JvThread1->Count);
|
|
lbCount2->Caption="Job2 count: "+IntToStr(JvThread2->Count);
|
|
|
|
if(JvThread1->Count==0) lbStats1->Caption = "ID:-------- V:-";
|
|
if(JvThread2->Count==0) lbStats2->Caption = "ID:-------- V:-";
|
|
|
|
cbJobTerminated1->Checked=JvThread1->Terminated;
|
|
cbJobTerminated2->Checked=JvThread2->Terminated;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::tmrAutoTimer(TObject *Sender)
|
|
{
|
|
if(cbAutoStart1->Checked)
|
|
{
|
|
if(rand()&1) btnStartJob1->Click();
|
|
else btnStartJob1SimpleDlg->Click();
|
|
}
|
|
|
|
if(cbAutoStart2->Checked)
|
|
{
|
|
if(rand()&1) btnStartJob2->Click();
|
|
else btnStartJob2AnimatedDlg->Click();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnSuspendItselfClick(TObject *Sender)
|
|
{
|
|
SuspendRandomThread=true;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnRaiseExceptionClick(TObject *Sender)
|
|
{
|
|
RaiseExceptInThread=true;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnRemoveZombieClick(TObject *Sender)
|
|
{
|
|
JvThread1->RemoveZombie();
|
|
JvThread2->RemoveZombie();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnShowStateClick(TObject *Sender)
|
|
{ // example of use JvThread->Threads[]
|
|
AnsiString s;
|
|
char c;
|
|
|
|
JvThread1->Lock();
|
|
try
|
|
{
|
|
if(JvThread1->Count)
|
|
{
|
|
Memo->Lines->Add("Job1 list");
|
|
Memo->Lines->Add("ID Active Finished Return Value");
|
|
for(int i=0; i<JvThread1->Count; ++i)
|
|
{
|
|
TJvBaseThread* T=JvThread1->Threads[i];
|
|
s=IntToHex((int)T->ThreadID, 8)+" ";
|
|
if(T->ExecuteIsActive) c='+'; else c='-'; s+=c; s+=" ";
|
|
if(T->Finished) c='+'; else c='-'; s+=c; s+=" ";
|
|
s+=IntToStr(T->ReturnValue);
|
|
Memo->Lines->Add(s);
|
|
}
|
|
}
|
|
else
|
|
Memo->Lines->Add("Job1 list is empty");
|
|
}
|
|
__finally
|
|
{
|
|
JvThread1->Unlock();
|
|
}
|
|
|
|
JvThread2->Lock();
|
|
try
|
|
{
|
|
if(JvThread2->Count)
|
|
{
|
|
Memo->Lines->Add("Job2 list");
|
|
Memo->Lines->Add("ID Active Finished Return Value");
|
|
for(int i=0; i<JvThread2->Count; ++i)
|
|
{
|
|
TJvBaseThread* T=JvThread2->Threads[i];
|
|
s=IntToHex((int)T->ThreadID, 8)+" ";
|
|
if(T->ExecuteIsActive) c='+'; else c='-'; s+=c; s+=" ";
|
|
if(T->Finished) c='+'; else c='-'; s+=c; s+=" ";
|
|
s+=IntToStr(T->ReturnValue);
|
|
Memo->Lines->Add(s);
|
|
}
|
|
}
|
|
else
|
|
Memo->Lines->Add("Job2 list is empty");
|
|
}
|
|
__finally
|
|
{
|
|
JvThread2->Unlock();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnExecuteAndWaitClick(TObject *Sender)
|
|
{
|
|
if(rand()&1) JvThread1->ThreadDialog = JvThreadSimpleDialog1;
|
|
else JvThread1->ThreadDialog = NULL;
|
|
|
|
Memo->Lines->Add("Execute and wait ...");
|
|
// JvThread1->ExecuteAndWait(NULL);
|
|
JvThread1->ExecuteThreadAndWait(NULL);
|
|
Memo->Lines->Add("Execute and wait: Done");
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::DynamicExecute(TObject *Sender, Pointer Params)
|
|
{
|
|
TJvBaseThread* ThisThread=dynamic_cast<TJvBaseThread*>(Sender);
|
|
if(ThisThread==NULL) // for testing only
|
|
throw Exception("Execution error: 'Sender' is not TJvBaseThread object");
|
|
|
|
if(ThisThread->Terminated)
|
|
{ // terminated before resume
|
|
ThisThread->ReturnValue=-1;
|
|
exit;
|
|
}
|
|
|
|
int i, j, k;
|
|
bool FL_Break=false;
|
|
|
|
ThisThread->ReturnValue=0;
|
|
|
|
k = 0;
|
|
for(i=0; i<1000 && !FL_Break; ++i)
|
|
{
|
|
for(j=0; j<10; ++j)
|
|
{
|
|
++k;
|
|
::Sleep(0);
|
|
Form1->ThreadID1 = ThisThread->ThreadID;
|
|
Form1->Value1 = k;
|
|
ThisThread->Synchronize(Form1->Stats1);
|
|
if(SuspendRandomThread)
|
|
{
|
|
SuspendRandomThread=false;
|
|
ThisThread->Suspend();
|
|
}
|
|
if(RaiseExceptInThread)
|
|
{
|
|
RaiseExceptInThread=false;
|
|
ThisThread->ReturnValue=666;
|
|
throw Exception("Exception in Job3, ThreadID="+IntToHex((int)ThisThread->ThreadID, 8));
|
|
}
|
|
if(ThisThread->Terminated)
|
|
{
|
|
FL_Break = true;
|
|
JvThread1->ReturnValue=1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TForm1::btnDynamicCreationClick(TObject *Sender)
|
|
{
|
|
TJvThread* Container=new TJvThread(NULL);
|
|
try
|
|
{
|
|
Container->OnBegin=(&JvThreadBegin);
|
|
Container->BeforeResume=(&JvThreadBeforeResume);
|
|
Container->OnExecute=(&DynamicExecute);
|
|
Container->ThreadDialog = JvThreadSimpleDialog3;
|
|
Memo->Lines->Add("Execute and wait Job3 ...");
|
|
Container->ExecuteAndWait(NULL);
|
|
Memo->Lines->Add("Execute and wait Job3: Done");
|
|
}
|
|
__finally
|
|
{
|
|
delete Container;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|