Delphi中多线程用Synchronize实现VCL数据同步显示
2010-03-10 00:41
531 查看
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);
Synchronize(WatchAction); {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误}
Sleep(500);
if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计}
begin
Synchronize(WatchAction);
Self.Suspend;
end;
end;
end;
{监视器显示统计信息}
procedure TRunningWatcher.WatchAction;
var
iSetCount:Integer;
dDiffTime,dPerSecond:Extended;
begin
iSetCount := ISetValueCount;
dDiffTime := 0;
dPerSecond := 0;
if not LessThan(EndCounter, BeginCounter) then
begin
dDiffTime := (EndCounter-BeginCounter)/CounterFrequency*1000.0;
dPerSecond := dDiffTime/dDiffTime*1000;
end;
Self.mThreadCount.Caption := IntToStr(list.Count);
Self.mThreadRun.Caption := IntToStr(ThreadCount);
Self.mThreadTerminate.Caption := IntToStr(list.Count-ThreadCount);
Self.mTotalCostTime.Caption := FormatFloat('0.00', CalSumValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mCallTimes.Caption := IntToStr(iSetCount);
Self.mAvgCostTime.Caption := FormatFloat('0.00', CalAvgValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mMaxCostTime.Caption := FormatFloat('0.00', CalcMaxValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mMinCostTime.Caption := FormatFloat('0.00', CalcMinValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mRunTime.Caption := FormatFloat('0.00', dDiffTime);
Self.mSynCallBack.Caption := FormatFloat('0.00', dPerSecond);
end;
程序说明:我这里定义了一些Tlabel的成员变量,根据构造函数来初始化成界面上的对应控件,在这里等同于界面上的label,在Execute函数中不停调用WatchAction过程,起先我的写法如下:
QueryPerformanceFrequency(CounterFrequency);
QueryPerformanceCounter(EndCounter);
WatchAction; {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误}
Sleep(500);
if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计}
begin
WatchAction;
Self.Suspend;
end;
在连续执行到9k次以上时,报“Canvas does not allow drawing”错误。修改后解决问题:
QueryPerformanceFrequency(CounterFrequency);
QueryPerformanceCounter(EndCounter);
Synchronize(WatchAction); {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误}
Sleep(500);
if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计}
begin
Synchronize(WatchAction);
Self.Suspend;
end;
如果在线程中对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);
Synchronize(WatchAction); {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误}
Sleep(500);
if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计}
begin
Synchronize(WatchAction);
Self.Suspend;
end;
end;
end;
{监视器显示统计信息}
procedure TRunningWatcher.WatchAction;
var
iSetCount:Integer;
dDiffTime,dPerSecond:Extended;
begin
iSetCount := ISetValueCount;
dDiffTime := 0;
dPerSecond := 0;
if not LessThan(EndCounter, BeginCounter) then
begin
dDiffTime := (EndCounter-BeginCounter)/CounterFrequency*1000.0;
dPerSecond := dDiffTime/dDiffTime*1000;
end;
Self.mThreadCount.Caption := IntToStr(list.Count);
Self.mThreadRun.Caption := IntToStr(ThreadCount);
Self.mThreadTerminate.Caption := IntToStr(list.Count-ThreadCount);
Self.mTotalCostTime.Caption := FormatFloat('0.00', CalSumValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mCallTimes.Caption := IntToStr(iSetCount);
Self.mAvgCostTime.Caption := FormatFloat('0.00', CalAvgValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mMaxCostTime.Caption := FormatFloat('0.00', CalcMaxValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mMinCostTime.Caption := FormatFloat('0.00', CalcMinValueE(CallServerTimeArr, 0, iSetCount-1));
Self.mRunTime.Caption := FormatFloat('0.00', dDiffTime);
Self.mSynCallBack.Caption := FormatFloat('0.00', dPerSecond);
end;
程序说明:我这里定义了一些Tlabel的成员变量,根据构造函数来初始化成界面上的对应控件,在这里等同于界面上的label,在Execute函数中不停调用WatchAction过程,起先我的写法如下:
QueryPerformanceFrequency(CounterFrequency);
QueryPerformanceCounter(EndCounter);
WatchAction; {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误}
Sleep(500);
if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计}
begin
WatchAction;
Self.Suspend;
end;
在连续执行到9k次以上时,报“Canvas does not allow drawing”错误。修改后解决问题:
QueryPerformanceFrequency(CounterFrequency);
QueryPerformanceCounter(EndCounter);
Synchronize(WatchAction); {必须让主线程来运行,否则会报"Canvas does not allow drawing"错误}
Sleep(500);
if ThreadCount = 0 then {如果线程全部退出,需要做最后一次统计}
begin
Synchronize(WatchAction);
Self.Suspend;
end;
相关文章推荐
- Delphi中多线程用Synchronize实现VCL数据同步显示 解决在线程中操作控件出现问题
- Delphi中多线程用Synchronize实现VCL数据同步显示
- Delphi中多线程用Synchronize实现VCL数据同步显示
- Delphi中多线程用Synchronize实现VCL数据同步显示
- Delphi中多线程用Synchronize实现VCL数据同步显示
- Delphi中多线程用消息实现VCL数据同步显示
- Delphi中多线程用消息实现VCL数据同步显示
- Delphi中多线程用消息实现VCL数据同步显示
- Delphi Dll中多线程无法使用Synchronize同步的解决方法(转)
- Delphi:与VCL同步(Synchronize()、用消息来同步)
- java(多线程)实现高性能数据同步
- Delphi多线程编程之同步读写全局数据
- Android 多线程 和异步的实践:跳转,同步显示时间,倒计时的实现,知识点
- ◆Delphi多线程编程之三 同步读写全局数据 ◆(乌龙哈里2008-10-12)
- 用Delphi在工业控制和自动化实现多线程进行数据采集
- 使用react实现手机号的数据同步显示功能的示例代码
- *Delphi:与VCL同步(Synchronize()、用消息来同步)
- vc嵌入Word后怎莫实现数据的同步刷新及在视图里显示所有文字
- 多线程编程13-----Exchanger同步工具类实现两线程数据交换
- 黑马程序员_Java基础:实现多线程对共有数据的同步操作