我现在做了一个即时显示信息的小软件,要求从服务器上即时显示服务端sql2000数据库中的信息,于是采用线程刷新客户端的办法,可这段程序,一会行,一会不行,有时则提:"在异步运行时,操作不能被执行",请各位老兄给指点一下,这样写有什么不对,我对线程不熟悉,原先采用定时器定时刷新,那样系统会占用大量系统资源,软件有假死现象
这是我定义的线程
TTestThread=class(tthread) //被测试线程,仅仅是将窗体的caption从0变到10000
protected
procedure Execute;override;
end;
TmThread=class(TThread) //检测线程,当被侧线程中止时,显示一个对话款
protected
procedure Execute;override;
end;
var
frmMain: TfrmMain;
t: TTestThread;
implementationuses ......procedure TTestThread.Execute; {TTestThread}
var
i:integer;
begin
FreeOnTerminate:=True;
dtmData.adtMsgInfo.requery;
dtmData.adtMsgInfo1.requery;
adtMsgInfo与adtMsgInfo1; //为sql2000服务器上的同一个表(一个用来显示全部信息,一个用来显示搜索信息)
end;procedure TmThread.Execute; {TmThread}
begin
if WaitForSingleObject(t.Handle,INFINITE)=WAIT_OBJECT_0 then
begin
Sleep(5000);
t:=TTestThread.Create(False);
TmThread.Create(False);
end;
//ShowMessage('线程已经中止');
end;
procedure TfrmMain.FormShow(Sender: TObject); //当开启主窗口时自动定时刷新数据
begin
t:=TTestThread.Create(False);
TmThread.Create(False);
end;
这是我定义的线程
TTestThread=class(tthread) //被测试线程,仅仅是将窗体的caption从0变到10000
protected
procedure Execute;override;
end;
TmThread=class(TThread) //检测线程,当被侧线程中止时,显示一个对话款
protected
procedure Execute;override;
end;
var
frmMain: TfrmMain;
t: TTestThread;
implementationuses ......procedure TTestThread.Execute; {TTestThread}
var
i:integer;
begin
FreeOnTerminate:=True;
dtmData.adtMsgInfo.requery;
dtmData.adtMsgInfo1.requery;
adtMsgInfo与adtMsgInfo1; //为sql2000服务器上的同一个表(一个用来显示全部信息,一个用来显示搜索信息)
end;procedure TmThread.Execute; {TmThread}
begin
if WaitForSingleObject(t.Handle,INFINITE)=WAIT_OBJECT_0 then
begin
Sleep(5000);
t:=TTestThread.Create(False);
TmThread.Create(False);
end;
//ShowMessage('线程已经中止');
end;
procedure TfrmMain.FormShow(Sender: TObject); //当开启主窗口时自动定时刷新数据
begin
t:=TTestThread.Create(False);
TmThread.Create(False);
end;
解决方案 »
- 很搞的问题,太搞了!
- 图标问题,如何提取图标文件里的图标?
- DBGrid中如何确定那一行被选择了?
- 200分送上,数据200万点如何打印?
- CSDN论坛助手 重出江湖!!!!爽!爽!!爽!!知道什么是极速吗?快来体验一下了。[周一早8:00发布]
- 帮忙,各位听过WORD2000里面有个合并列印的功能吗,在什么地方的,
- 帮看看:ADOConnection1.ConnectionString:='Remote Provider={SQL Server};'....我想连不同域的另一台MS SQL SERVER 2000.
- 如何用opendialog获得选择文件的扩展名?
- 有无API函数可获知webbrowser控件滚动条当前所在位置?拜托了!
- 请问delphi如何加入MDI窗体?
- 为什么我在VB中用ADO打开DB数据库必须要管理员才行?
- ■■■ 很有挑战性的题目 ■■■
5s啊
Sleep的时间是不是有点长了
你的线程也没有挂起
procedure TmThread.Execute; {TmThread}
begin
if WaitForSingleObject(t.Handle,INFINITE)=WAIT_OBJECT_0 then
begin
Sleep(5000);
t:=TTestThread.Create(False);
TmThread.Create(False);
end;
//ShowMessage('线程已经中止');
end; 一条条语句来分析:
if WaitForSingleObject(t.Handle,INFINITE)……
这里t如果是nil呢?
t:=TTestThread.Create(False); 你的TTestThread只执行一次操作,这个操作为何不直接写为TmThread的一个函数(/过程)?
TmThread.Create(False); 这个东东干啥?
似乎你的思路没理好。
还有不要直接调用外部的数据集,有用到数据集的话应该在线程里创建数据集
看过TThread类的源码就可以知道它所同步的过程代码将会被放到主线程执行.以便不会同时出现多个线程
同时操作一个界面上的元素.
我觉得楼主的这个同步方式看着很别扭.你可以用信号量来做同步的啊(参见CreateSemaphore,OpenSemaphore及WaitForSingleObject).
while not terminated do
begin
if 情况A标志 then
begin
处理情况A;
情况A标志 := false;
end; 记时;
if 时间到 then
begin
处理情况B;
重启记时;
end;
end;在你的例子中,上面的情况A可以是某些操作数据库的操作;情况B则是你定时的显示操作。我一般的操作方式是:建立一个任务列表,有任务就往列表中加,线程的处理则是循环检测任务是否为空,不为空则取出任务处理,进行相关处理。这就是“生产-消费者”模式。保证各任务是排队处理,不会造成某项任务没完成,另一个任务立即去制造混乱(举例:比如你两个处理用到同一个组件,一个要求查询,一个要求插入,就会造成冲突……)。
当然,同步,是要做的。
你主要的问题是思路没理清。
procedure TZDBThread.Execute;
begin
while Trud do
begin
读取数据库
end;
end;但最好的办法是不要数据库绑定,创建一个列表保存返回结果procedure TZDBThread.Execute;
var
ADOQ:TADOQuery
begin
创建ADOQ
while Trud do
begin
读取数据库
将结果保存在一个列表中.如果不同时给窗体发送消息,将结果显示
Postmessag(窗体Handle ,自己定义的消息,0,0);
如果相同则不发送消息.
Sleep(刷新的时候间隔);
end;
ADOQ.Free;
end;