小弟做了个类似于选号的程序,思路是这样的:
在一个数据库(名字叫Code)中存大量的号码,一个字段是 Num 放号码,一个字段是 Used 做为Boolean型的标志位,初始时都是False,代码所有号码都没被用过。
然后在程序中设置一个 Flag 是Boolean型的标志位,控制循环,初始是True。
然后在窗体上放两个按钮一个 Start 一个 Stop,Start点击后打开数据库开始循环显示号码(没用过的),Stop点击后停止循环,窗口中显示的会停在一个号码上,然后打开数据库查找到显示的那个号码,把它的Used字段值改为True,代表这个号被用过了。一开始没用线程做,直接用的一个While(Flag),点击Stop按钮后就把Flag改为False希望把无限循环停下来,但是实际上点了Start按钮后程序就一直飞快的在那里无限循环,根本响应不了点击Stop按钮的操作。后来没办法现学现卖用了WinAPI的CreateThread函数来创建线程处理无限循环,这样才能响应点击Stop按钮的操作。但是问题来了,线程中的无限循环大致是这样的:With Query_Code do
begin
Close;
SQL.Clear;
SQL.ADD('Select Num from Code where Used = "False"');
Open;
First;
while (Flag) do
begin
Edit1.Text := FieldByName('Num').AsString; //在窗体上显示当前的号码
Edit1.Refresh;
if EOF
then First; //如果到了数据集的最后就返回到第一个
else Next; //如果不是最后一个就向后移动
end;
Close;
end;然后Stop按钮的代码大致如下:Flag := False;
With Query_Code do
begin
Close;
SQL.Clear;
SQL.ADD('Select * from Code where Num = ' + Edit1.Text);
Open;
Edit;
FieldValues['Used'] := True;
Post;
Close;
end;
开始跑线程后,点Stop就会报错说无法对只读的数据库进行写操作。我估计是虽然Flag置了False使窗口上显示的号码停了下来,但是仿佛线程根本没结束没关闭,数据库还开着,所以Stop里对数据库的Post操作非法,尽管用了Edit过程想把数据库置为可编辑状态。请问我该如何确定线程已经彻底关闭,数据库被释放出来?
或者说我该使用一种什么手段来有效的停止线程,好象有看到说用Flag这种标志位在线程里用着是有什么问题。我的线程没用TThread类,直接用的WinAPI。第一次尝试线程的编程,太多东西不熟悉了。
或者不用线程能解决那种无限循环后程序无法响应点击按钮的问题吗?
在一个数据库(名字叫Code)中存大量的号码,一个字段是 Num 放号码,一个字段是 Used 做为Boolean型的标志位,初始时都是False,代码所有号码都没被用过。
然后在程序中设置一个 Flag 是Boolean型的标志位,控制循环,初始是True。
然后在窗体上放两个按钮一个 Start 一个 Stop,Start点击后打开数据库开始循环显示号码(没用过的),Stop点击后停止循环,窗口中显示的会停在一个号码上,然后打开数据库查找到显示的那个号码,把它的Used字段值改为True,代表这个号被用过了。一开始没用线程做,直接用的一个While(Flag),点击Stop按钮后就把Flag改为False希望把无限循环停下来,但是实际上点了Start按钮后程序就一直飞快的在那里无限循环,根本响应不了点击Stop按钮的操作。后来没办法现学现卖用了WinAPI的CreateThread函数来创建线程处理无限循环,这样才能响应点击Stop按钮的操作。但是问题来了,线程中的无限循环大致是这样的:With Query_Code do
begin
Close;
SQL.Clear;
SQL.ADD('Select Num from Code where Used = "False"');
Open;
First;
while (Flag) do
begin
Edit1.Text := FieldByName('Num').AsString; //在窗体上显示当前的号码
Edit1.Refresh;
if EOF
then First; //如果到了数据集的最后就返回到第一个
else Next; //如果不是最后一个就向后移动
end;
Close;
end;然后Stop按钮的代码大致如下:Flag := False;
With Query_Code do
begin
Close;
SQL.Clear;
SQL.ADD('Select * from Code where Num = ' + Edit1.Text);
Open;
Edit;
FieldValues['Used'] := True;
Post;
Close;
end;
开始跑线程后,点Stop就会报错说无法对只读的数据库进行写操作。我估计是虽然Flag置了False使窗口上显示的号码停了下来,但是仿佛线程根本没结束没关闭,数据库还开着,所以Stop里对数据库的Post操作非法,尽管用了Edit过程想把数据库置为可编辑状态。请问我该如何确定线程已经彻底关闭,数据库被释放出来?
或者说我该使用一种什么手段来有效的停止线程,好象有看到说用Flag这种标志位在线程里用着是有什么问题。我的线程没用TThread类,直接用的WinAPI。第一次尝试线程的编程,太多东西不熟悉了。
或者不用线程能解决那种无限循环后程序无法响应点击按钮的问题吗?
解决方案 »
- 像TWebBrowser这类ActiveX控件,如何设置Parent控件﹖
- 问个很菜的问题:窗体继承在程序开发中的作用是什么?
- 如何实现象MSN中那样的闪屏振动功能?
- 如果让一个biBitCount=8的位图与一个DC兼容!
- 谁有胆量挑战“流”?就把此问题处理了。
- 她是不是偶的女朋友,进来看看,现代版廊桥遗梦,呜呜呜!
- 面试试题。
- [Error] WARNING. Duplicate resource(s):
- MTS_COM中为什么用DCOMConnection连接时会出现"Server Excetion failed"
- 备份数据库
- 大虾们,帮我推荐些多维图表展示的Delphi组件
- 简单的报表预览问题
修改数据库用update语句实现
线程循环中添加个Sleep(10)
stop按钮只修改flag值
把所有的实现代码全放到一个线程里stop按钮只修改一个标志位 Stopped:=True;在线程里判断Stopped是否为True 是的话执行你的操作并关闭数据库另外
在线程中操作VCL需要用Synchronize(your procedure)的方式
Application.ProcessMessages;
if Stopped then
结束
else
begin
//your code
end;Stop按钮只修改一个变量 不要进行其他操作
if ExportFileInfo.isFilesUp then
begin
StringList:=ExportFileInfo.getUpFileList; //获取导出文件目录下的文件列表
while StringList.Count>0 do
begin
i:=StringList.Count-1;
clientSockThread:=TClientSockThread.create();//ServerInfo
clientSockThread.upFileName:=StringList.Strings[i]; //所要上传的文件名称:1.txt
//clientSockThread.TExportInfo:=exportInfo;
filePath:= ExportInfo.ExportPath+'\export\'+StringList.Strings[i];
DeleteFile(pchar(filePath));
StringList:=ExportFileInfo.getUpFileList; //重新获取文件列表
sleep(200);
end;
StringList.Free;
end;
end;