在下面的情况下,有人可以提供如何实现我想要的建议吗? (我想知道theads是否有帮助,但之前没有使用它们。)
在我的Delphi应用程序中,我有一个通过Internet运行外部MYSQL数据库的查询。查询结果显示在DBGrid中(最多50行)。
用户点击按钮进行“网络检查”,然后发生以下情况......
首先,我将数据集的一个字段(web_response)设置为空字符串,以清除DBGrid中显示的任何现有数据。
然后,对于数据集中的每一行,我提取一个字段的值(FieldA),将其传递给一个函数,并将另一个字段(web_response)的值设置为该函数的结果。
该函数本身使用IdHTTP使用传递的参数在不同的远程网站上执行搜索并返回响应字符串。该过程大约需要1到2秒。
我想要的效果是让网格“瞬间”清除所有网络响应字段,然后逐行将网络响应字段设置为一个值,每个值都会在设置时显示。
下面的代码工作正常,但不能完全达到我需要的效果。我想知道是否在某处使用线程 - 而不是application.processmessages可能会改进。
此刻我得到的效果是网格在一两秒内完全消失,然后重新出现,网络响应列为空白。 然后使用Web响应以每1秒一行的速率更新行,但每次添加新响应时网格都会剧烈闪烁。 如果线程没有帮助,有没有更好的方法来做我正在做的事情?
我目前使用的代码(更改标识符以保护无辜者)
//empty any preexisting web responses
//disable controls to stop the DBgrid flickering while we clear out existing web responses
DBGrid1.DataSource.DataSet.DisableControls;
MyQuery1.First;
while not MyQuery1.Eof do
begin
MyQuery1.Edit;
MyQuery1.FieldByName('web_response').AsString := '';
MyQuery1.Next;
end;
DBGrid1.RefreshData; //show cleared grid again
DBGrid1.DataSource.DataSet.EnableControls;
//For each row, check FieldA on the web and show response
MyQuery1.First;
while not MyQuery1.Eof do
begin
DataToCheck := MyQuery1.FieldByName('FieldA').AsString ; //get data to check
//get the web response and put into dataset
MyQuery1.Edit;
MyQuery1.FieldByName('web_response').AsString := GetWebCheckResponse(DataToCheck);
Application.ProcessMessages; //,'cos the loop is slow <<-- can I get rid of this and use threads?
DBGrid1.RefreshData; //show the response we just put in dataset
MyQuery1.Next;
end;
答案 0 :(得分:1)
自从我上次接触Delphi以来已经超过7年了,我们不允许使用数据感知组件,所以我可能会在这里给你错误的建议。但是,您似乎经常刷新网格。特别是你在循环中刷新网格。
我建议将代码更改为:
DBGrid1.DataSource.DataSet.DisableControls;
MyQuery1.First;
while not MyQuery1.Eof do
begin
MyQuery1.Edit;
MyQuery1.FieldByName('web_response').AsString := '';
MyQuery1.Next;
end;
//For each row, check FieldA on the web and show response
MyQuery1.First;
while not MyQuery1.Eof do
begin
DataToCheck := MyQuery1.FieldByName('FieldA').AsString ; //get data to check
//get the web response and put into dataset
MyQuery1.Edit;
MyQuery1.FieldByName('web_response').AsString := GetWebCheckResponse(DataToCheck);
Application.ProcessMessages; //,'cos the loop is slow <<-- can I get rid of this and use threads?
MyQuery1.Next;
end;
DBGrid1.DataSource.DataSet.EnableControls;
DBGrid1.RefreshData; //show the response we just put in dataset
您可能希望显示一个说明处理的对话框,并且在完成所有操作之前不显示网格。你可能想查看DBGrid.BegingUpdate()和DBGrid.EndUPdate(),如果内存服务我的话。
答案 1 :(得分:0)
我只使用进度条和progressbar1.repaint;在循环中刷新进度,而不是application.processmessages;
答案 2 :(得分:0)
DBGrid1.DataSource.DataSet.DisableControls;
MyQuery1.First;
while not MyQuery1.Eof do
begin
MyQuery1.Edit;
MyQuery1.FieldByName('web_response').AsString := '';
MyQuery1.Next;
end;
DBGrid1.DataSource.DataSet.EnableControls;
DBGrid1.RefreshData;
Application.ProcessMessages;
//For each row, check FieldA on the web and show response
MyQuery1.First;
while not MyQuery1.Eof do
begin
DataToCheck := MyQuery1.FieldByName('FieldA').AsString ; //get data to check
//get the web response and put into dataset
MyQuery1.Edit;
MyQuery1.FieldByName('web_response').AsString := GetWebCheckResponse(DataToCheck);
MyQuery1.Next;
DBGrid1.RefreshData;
Application.ProcessMessages;
end;
干杯, 范