读书人

cxgrid多线程怎么操作

发布时间: 2012-12-17 09:31:40 作者: rapoo

cxgrid多线程如何操作?
本帖最后由 hzken0137 于 2012-02-15 13:31:29 编辑 各位好:
刚刚接触多线程,自己尝试了一下,经常报错,显示类似“Access violation at address 004e5379 in module”, 不知道怎么写才是对了。

我做的是个测试的程序,有一个表格,程序一行一行运行下去,焦点也跟着下去,同时根据结果,行显示对应的颜色。
我现在写的是示例,界面如下

点击“单线程按钮”后,效果

单线程的代码如下


procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
begin
with cxgrdbtblvw_List do
begin
DataController.RecordCount:=25;
BeginUpdate;
for i:=0 to DataController.RecordCount-1 do
begin
DataController.Values[i,cxgrdbclmn_ID.Index]:=IntToStr(i+1);
DataController.Values[i,cxgrdbclmn_TestItem.Index]:='测试项'+IntToStr(i+1);
end;
EndUpdate;
end;
end;
//画颜色
procedure TForm1.cxgrdbtblvw_ListCustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
var
ARec: TRect;
begin
if AViewInfo.RecordViewInfo.GridRecord.Values[8] ='PASS' then
begin
ARec := AViewInfo.Bounds;
ACanvas.canvas.brush.color:= clGreen;
ACanvas.FillRect(ARec);
end;
if AViewInfo.RecordViewInfo.GridRecord.Values[8] ='FAIL' then
begin
ACanvas.Brush.Color:= clRed;
end;
end;
//单线程按钮事件
procedure TForm1.btn1Click(Sender: TObject);
var
i,j:Integer;
s:string;
MyThread:TMyThread;
begin
cxgrid1.SetFocus;
if Timer1.Enabled=true then
begin
Timer1.Enabled:=False;
end
else
begin
Timer1.Enabled:=True;
edt1.Text:='00:00';
end;
with cxgrdbtblvw_List do
begin
for i:=0 to DataController.RecordCount-1 do
begin
DataController.Values[i,cxgrdbclmn_Result.Index]:='';
end;
for i:=0 to DataController.RecordCount-1 do
begin
Sleep(100);
Application.ProcessMessages;
Controller.FocusedRowIndex:=i;
DataController.Values[i,cxgrdbclmn_Result.Index]:='PASS';
if (i>7) and (i<20) then
begin
DataController.Values[i,cxgrdbclmn_Result.Index]:='FAIL';
DataController.Values[i,cxgrdbclmn_Result.Index]:='FAIL';
end;
TrkPercent.Position:=trunc(((i+1)/DataController.RecordCount)*100);
RZPrb1.Percent:= trunc(((i+1)/DataController.RecordCount)*100);
cxProgressBar1.Position:= trunc(((i+1)/DataController.RecordCount)*100);


end;
Timer1.Enabled:=False;
end;
end;
Time事件
procedure TForm1.Timer1Timer(Sender: TObject);
var
mm,ss:Integer;
Led,H,F,S:string;
begin
Led:=edt1.Text ;
mm:=StrToInt(Copy(Led,1,2));
ss:=StrToInt(Copy(Led,4,2));
ss:=ss+1;
if ss>59 then
begin
mm:=mm+1;
ss:=0;
end;
if ss<10 then
S:='0'+IntToStr(ss)
else
S:=IntToStr(ss);
if mm<10 then
H:='0'+IntToStr(mm)
else
H:=IntToStr(mm);
edt1.Text :=H+':'+S;
end;



问题:单线程下,要是按住程序标题栏,界面显示就暂停了,如何将之变为多线程?
==============================
但是我尝试着改成多线程,运行的时候,老是出错

procedure TForm1.btn2Click(Sender: TObject);
var
i:Integer;
ID: DWORD;
CSThread:TTestThread;
begin
CSThread:=TTestThread.Create(False);
end;

unit TestThread;

interface

uses
Classes;

type
TTestThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;

implementation

uses Unit1;

procedure TTestThread.Execute;
var
i:Integer;
begin
with Form1.cxgrdbtblvw_List do
begin
for i:=0 to DataController.RecordCount-1 do
begin
Controller.FocusedRowIndex:=i;
DataController.Values[i,Form1.cxgrdbclmn_Result.Index]:='PASS';
if (i>7) and (i<20) then
begin
DataController.Values[i,Form1.cxgrdbclmn_Result.Index]:='FAIL';
DataController.Values[i,Form1.cxgrdbclmn_Result.Index]:='FAIL';
end;
Form1.TrkPercent.Position:=trunc(((i+1)/DataController.RecordCount)*100);
Form1.RZPrb1.Percent:= trunc(((i+1)/DataController.RecordCount)*100);
Form1.cxProgressBar1.Position:= trunc(((i+1)/DataController.RecordCount)*100);
end;
Form1.Timer1.Enabled:=False;
end;
end;

end.


在线等,谢谢
我把TestThread单元改成这样,虽然运行没有出错,但不是我要的一行一行逐一运行下去的效果,
而是一下子出现的效果

procedure TTestThread.Execute;
var
i:Integer;
begin
Synchronize(update);
end;
procedure TTestThread.update;
var
i:Integer;
begin
with Form1.cxgrdbtblvw_List do
begin
for i:=0 to DataController.RecordCount-1 do


begin
Controller.FocusedRowIndex:=i;
DataController.Values[i,Form1.cxgrdbclmn_Result.Index]:='PASS';
if (i>7) and (i<20) then
begin
DataController.Values[i,Form1.cxgrdbclmn_Result.Index]:='FAIL';
DataController.Values[i,Form1.cxgrdbclmn_Result.Index]:='FAIL';
end;
Form1.TrkPercent.Position:=trunc(((i+1)/DataController.RecordCount)*100);
Form1.RZPrb1.Percent:= trunc(((i+1)/DataController.RecordCount)*100);
Form1.cxProgressBar1.Position:= trunc(((i+1)/DataController.RecordCount)*100);
end;
Form1.Timer1.Enabled:=False;
end;
end;


[最优解释]
帮楼主顶顶,你说一下子出现了,会不会是运行太快的。
加个sleep试试。

我觉得这类功能,你用个Timer也可以,并且容易控制。
因为是客户端程序,Timer引起的内问题基本无需考虑。
[其他解释]
知道今天是情人节,各位都很忙,不过请抽点时间给看看,谢谢了
[其他解释]
天哪,竟然没有回复,~~
[其他解释]
继续顶,悲剧啊
[其他解释]
谢谢帮顶, 试过在procedure TTestThread.update;里增加Sleep(1000);但是卡的要命,比单线程都不如

读书人网 >.NET

热点推荐