首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

cxgrid多线程怎么操作

2012-12-17 
cxgrid多线程如何操作?本帖最后由 hzken0137 于 2012-02-15 13:31:29 编辑各位好:刚刚接触多线程,自己尝试

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);但是卡的要命,比单线程都不如

热点排行