+ -
当前位置:首页 → 问答吧 → 多线程赋值ClientDataSet报错,麻烦大牛们帮看下代码!

多线程赋值ClientDataSet报错,麻烦大牛们帮看下代码!

时间:2011-08-27

来源:互联网

数据少的时候没什么问题,数据量大就报错(大概超过200K的TXT数据就报错了),而且赋值的时候而尔会出现丢数据现象。
搞了一个晚上,没查出来问题出在哪里。。。快要崩溃了,只能来这里求助了。
难道是我哪里写的有问题?麻烦各位大牛给看下!分少可以再加。。。各位救急下!

Delphi(Pascal) code

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DBGridEhGrouping, StdCtrls, GridsEh, DBGridEh, DB, DBClient;

type
  TForm1 = class(TForm)
    dbgrdh2: TDBGridEh;
    btn1: TButton;
    ds3: TDataSource;
    ds2: TClientDataSet;
    tmfldds2CDSDesigner: TTimeField;
    fltfldds2CDSDesigner2: TFloatField;
    fltfldds2T1: TFloatField;
    fltfldds2F1: TFloatField;
    fltfldds2T2: TFloatField;
    fltfldds2F2: TFloatField;
    procedure btn1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TThreadRead = class(TThread)
  private
    MyLog,Temp1,Temp2:TStringList;
    Stream:TFileStream;
    FDataSource:TDataSource;
    FCDS:TClientDataSet;
  procedure ConnectDataSource;
  protected
    procedure Execute;override;
  public
    constructor Create(ClientDataSet:TClientDataSet;
    DataSource:TDataSource);virtual;
    destructor Destroy; override;

  end;

var
  Form1: TForm1;


implementation
var
    FDataSet : TThreadRead;

{$R *.dfm}
function  Decrypt(Src:String; Key:String):String;stdcall;
  var   KeyLen,KeyPos,Offset,SrcPos,SrcAsc,TmpSrcAsc:Integer;
          Dest:String;
  begin
      KeyLen:=Length(Key);
      if   KeyLen = 0 then Key:='Windows XP';
      KeyPos:=0;
      Offset:=StrToInt('$'+   Copy(Src,1,2));
      SrcPos:=3;
      repeat
          SrcAsc:=StrToInt('$'+   Copy(Src,SrcPos,2));   
          if   KeyPos   <   KeyLen   Then   KeyPos   :=   KeyPos   +   1   
              else   KeyPos   :=   1;   
          TmpSrcAsc   :=   SrcAsc   xor   Ord(Key[KeyPos]);
          if   TmpSrcAsc<=Offset   then   TmpSrcAsc:=255+TmpSrcAsc-Offset   
              else   TmpSrcAsc:=TmpSrcAsc-Offset;   
          Dest:=Dest   +   Chr(TmpSrcAsc);
          Offset:=SrcAsc;
          SrcPos:=SrcPos+2;
      until   SrcPos>=Length(Src);
      Result:=Dest;
  end;


procedure TThreadRead.ConnectDataSource;
begin
FDataSource.DataSet := FCDS;
end;

destructor TThreadRead.Destroy;
begin
  MyLog.Free;
  Temp1.Free;
  Temp2.Free;
  Stream.Free;
  FDataSource.Free;
  FCDS.Free;
end;

procedure TThreadRead.Execute;{ 执行线程的方法 }
var
  i:Integer;
  MyKey:string;
begin
try
  MyKey:='Bung';
  MyLog:=TStringList.Create();
  Temp1:=TStringList.Create();
  Temp2:=TStringList.Create();
  stream:=TFileStream.Create('e:\\1.TXT',fmOpenRead);
  MyLog.LoadFromStream(stream);

  for i:=0 to MyLog.count-1 do
  begin
    TEMP1.Add(Decrypt(MyLog.strings[i],MyKey));
  end;

  with FCDS do
  begin
  Close;
  CreateDataSet;
  Append;
  Temp2.Delimiter := '|';
  for i:=TEMP1.Count-1 downto 0 do
  begin
  Sleep(10);
  Temp2.Clear;
  Temp2.DelimitedText :=trim(TEMP1.strings[i]);
  Insert;
  FieldByName('时间').AsDateTime:=StrToDateTime(Temp2.Strings[0]);
  FieldByName('数据1').AsFloat:=StrToFloat(Temp2.Strings[1]);
  FieldByName('数据2').AsFloat:=StrToFloat(Temp2.Strings[2]);
  FieldByName('数据3').AsFloat:=StrToFloat(Temp2.Strings[3]);
  FieldByName('数据4').AsFloat:=StrToFloat(Temp2.Strings[4]);
  FieldByName('数据5').AsFloat:=StrToFloat(Temp2.Strings[5]);
  end;
  end;

 Synchronize(ConnectDataSource);{ 线程同步 }

except 
ShowMessage('Error'); { 线程异常 }
end;
end;

{ 线程查询类的构造器 }
constructor TThreadRead.Create(ClientDataSet:TClientDataSet; DataSource:TDataSource);
begin

  FCDS:=ClientDataSet;
  FDataSource:=DataSource;

  inherited Create(True);
  FreeOnTerminate := False;
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
FDataSet := TThreadRead.Create(ds2, ds3);
FDataSet.Resume;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if FDataSet<>nil then
  begin
  FDataSet.Terminate;
  FDataSet.Destroy;
  end;

end;

end.

作者: aBung   发布时间: 2011-08-27

数据源是同一个吗?多线程读同一个文件要。。。。。。
每个线程都只访问自己创建的ClientDataSet,那应该没问题
CreateDataSet没代码,是每个线程都创建自己的ClientDataSet吗?

作者: sz_haitao   发布时间: 2011-08-27

楼主的命名规范让本菜 十分蛋疼,

作者: SS_LO   发布时间: 2011-08-27

数据源就是一个TXT文件,里面大概有3W条数据

1、将TXT的数据读入StringList;
2、分别用2个线程去读取StringList的内容,一个从0-1.5W读取,一个从1.6-3.0W开始读取;
3、合并输出至ClientDataSet显示。

作者: aBung   发布时间: 2011-08-27

热门下载

更多