在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
VCL实现同步方法就是调用线程类的Synchronize的过程,此过程需要一个无参数的procedure,故在此procedure中无法传递参数值,但可以通过类的成员来实现。在类的Execute中只须调用Synchronize就可以了。 如果在线程中对VCL赋值操作,在连续执行多次以后,会报“Canvas does not allow drawing”错误,这个错误可以由上述方法修复,把赋值操作让窗体主线程来完成。 关键在于对Synchronize参数的定义。定义一个无参数的procedure通过它来访问类的成员变量szName和nIndex。在类的重载Execute中调用Synchronize。 例证代码: 1
2 procedure TRunningWatcher.Execute; 3 begin 4 {do some thing here} 5 FreeOnTerminate := True; 6 while (not Terminated) and (not Application.Terminated) do 7 begin 8 QueryPerformanceFrequency(CounterFrequency); 9 QueryPerformanceCounter(EndCounter); 10 Synchronize(WatchAction); {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误} 11 Sleep(500); 12 if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计} 13 begin 14 Synchronize(WatchAction); 15 Self.Suspend; 16 end; 17 end; 18 end; 19 20 {监视器显示统计信息} 21 procedure TRunningWatcher.WatchAction; 22 var 23 iSetCount:Integer; 24 dDiffTime,dPerSecond:Extended; 25 begin 26 iSetCount := ISetValueCount; 27 dDiffTime := 0; 28 dPerSecond := 0; 29 if not LessThan(EndCounter, BeginCounter) then 30 begin 31 dDiffTime := (EndCounter-BeginCounter)/CounterFrequency*1000.0; 32 dPerSecond := dDiffTime/dDiffTime*1000; 33 end; 34 Self.mThreadCount.Caption := IntToStr(list.Count); 35 Self.mThreadRun.Caption := IntToStr(ThreadCount); 36 Self.mThreadTerminate.Caption := IntToStr(list.Count-ThreadCount); 37 Self.mTotalCostTime.Caption := FormatFloat('0.00', CalSumValueE(CallServerTimeArr, 0, iSetCount-1)); 38 Self.mCallTimes.Caption := IntToStr(iSetCount); 39 Self.mAvgCostTime.Caption := FormatFloat('0.00', CalAvgValueE(CallServerTimeArr, 0, iSetCount-1)); 40 Self.mMaxCostTime.Caption := FormatFloat('0.00', CalcMaxValueE(CallServerTimeArr, 0, iSetCount-1)); 41 Self.mMinCostTime.Caption := FormatFloat('0.00', CalcMinValueE(CallServerTimeArr, 0, iSetCount-1)); 42 Self.mRunTime.Caption := FormatFloat('0.00', dDiffTime); 43 Self.mSynCallBack.Caption := FormatFloat('0.00', dPerSecond); 44 end;
程序说明:我这里定义了一些Tlabel的成员变量,根据构造函数来初始化成界面上的对应控件,在这里等同于界面上的label,在Execute函数中不停调用WatchAction过程,起先我的写法如下:
1 QueryPerformanceFrequency(CounterFrequency); 2 QueryPerformanceCounter(EndCounter); 3 WatchAction; {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误} 4 Sleep(500); 5 if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计} 6 begin 7 WatchAction; 8 Self.Suspend; 9 end;
在连续执行到9k次以上时,报“Canvas does not allow drawing”错误。修改后解决问题: 1 QueryPerformanceFrequency(CounterFrequency);
2 QueryPerformanceCounter(EndCounter); 3 Synchronize(WatchAction); {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误} 4 Sleep(500); 5 if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计} 6 begin 7 Synchronize(WatchAction); 8 Self.Suspend; 9 end;
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论