帮帮我!为什么在线程里打开TClientDataSet有问题?第一次用线程,多多指教。 (50分)

  • 主题发起人 主题发起人 szkok
  • 开始时间 开始时间
S

szkok

Unregistered / Unconfirmed
GUEST, unregistred user!
大侠打救我!为什么在线程里打开TClientDataSet有问题?出错后再去打开的话就死机了,我想应是线程没释放,对这此意外事件,应在哪释放线程?第一次用线程,多多指教。
我的代码(我简化了的)如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, DBClient, MConnect, SConnect;
type
TForm1 = class(TForm)
SocketConnection1: TSocketConnection;
ClientDataSet1: TClientDataSet;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

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

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TMyThread.Execute;
begin
FreeOnTerminate:=True;
Form1.ClientDataSet1.Close;
Form1.ClientDataSet1.CommandText:='select * from Unit';
Form1.ClientDataSet1.Open;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
mm:TMyThread;
begin
mm:=TMyThread.Create(False);
end;

end.
 
这是因为Delphi线程不安全的问题引起的,即VCL只能在一个时刻被一个线程访问。
 
没有解决的办法吗?
 
一个比较简单的解决办法就是通过向主线程发送消息来实现消息同步。把
Form1.ClientDataSet1.Close;
Form1.ClientDataSet1.CommandText:='select * from Unit';
Form1.ClientDataSet1.Open;
放进主线程的消息处理函数里面去。
 
即使是一个线程访问,也是出错的。
其实我程序就是只使用一个线程,我使用线程是为了在数据交换时不让界面死着不能动。
 
procedure TMyThread.Execute;
begin
FreeOnTerminate:=True;
SendMessage(Form1.Handle,自定义消息,0,0);
end;
 
那你在单线程环境下出错的地方是在哪里?
 
Form1.ClientDataSet1.Open;
就在这里
 
Form1.ClientDataSet1.Open;//这里出错
如果不是在线程里OPEN的话,就不会出错
 
procedure mythread.doexecute;
begin
Form1.ClientDataSet1.Close;
Form1.ClientDataSet1.CommandText:='select * from Unit';
Form1.ClientDataSet1.Open;
end;

procedure TMyThread.Execute;
begin
FreeOnTerminate:=True;
Synchronize(doexecute);
end;
 
那就是线程安全的问题啊,jerry529兄台给你的方法也可以,都是为了使消息同步。
 
jerry529:
你的方法不行啊,我试了,机子就死掉了
 
那你试过我的发送消息没有。应该没问题的。
 
都不行,我的机子死掉了N次。
其实我使用线程是为了在数据交换时(可能有半个小时久)不让界面死着不能动,听说不用线程也可以的,大侠们有什么好的方法吗?帮帮我吧!
 
是不是应该把ClientDataSet1放到你的线程里去工作?
 
不好意思,太忙了,没时间上来。看来也没人答了,发分。
 
后退
顶部