如何搜索性能更佳的每个字符?

时间:2013-11-28 14:10:52

标签: delphi

我有一个搜索字段,用户搜索每个输入的字符。所以没有搜索按钮。问题是搜索速度很慢。我的想法是在每个键输入一点后延迟搜索,所以如果用户快速输入搜索字符串,则允许不搜索。然后执行搜索。我的代码到目前为止。

procedure TAgreementModuleForm.SetIsSearching(const Value: Boolean);
begin
  fIsSearching := Value;
  tmrDelayKey.Enabled := Value;
end;

procedure TAgreementModuleForm.tmrDelayKeyTimer(Sender: TObject);
begin
  IsSearching := True;
end;

procedure TAgreementModuleForm.txtSearchAgreementCustomerExit(Sender: TObject);
begin
  IsSearching := False;
end;

procedure TAgreementModuleForm.txtSearchAgreementCustomerKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  vSearchExpression: string;
begin
  if IsSearching then
  begin
    vSearchExpression := Trim(txtSearchAgreementCustomer.Text);
    IsSearching := False;
    if vSearchExpression <> '' then
      DoSearch(vSearchExpression);
  end
  else
    tmrDelayKey.Enabled := True;
end;

tmrDelayKey是一个延迟为1000毫秒的TTimer。 IsSearching是一个布尔属性。

这不是工作代码,因为用户停止编写搜索。 如何改进?

2 个答案:

答案 0 :(得分:5)

根本问题是您的搜索是同步的并且阻止了UI。添加延迟并没有多大帮助。用户获取反馈需要更长的时间。

您需要做的是异步执行搜索。比如把它放在另一个线程中。搜索完成后,发出主线程信号,以便显示结果。如果用户在搜索完成之前键入,则应使用更新的搜索词重新开始搜索。

此方法可为您提供响应式用户界面,并尽快提供搜索结果。

注意:我假设您没有理由避免重复搜索。如果搜索成本很高,那么您绝对不希望在键入时实现搜索。

答案 1 :(得分:2)

我相信这段代码应该有效:

var SearchComplete: Boolean;

procedure TForm1.DoSearch(Astring: String);
begin
  SearchComplete:= True;
  txtSearchAgreementCustomer.Text := 'Searched: '+Astring;
end;

procedure TForm1.tmrDelayKeyTimer(Sender: TObject);
begin
  if not SearchComplete then
  begin
    DoSearch(txtSearchAgreementCustomer.Text);
  end;
end;

procedure TForm1.txtSearchAgreementCustomerKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var C: Char;
begin
  C:= Char(Key);
  if (C in ['a' .. 'z']) or (C in ['A' .. 'Z']) or (C in ['0'..'9']) then
    SearchComplete := False;
end;


procedure TForm1.txtSearchAgreementCustomerExit(Sender: TObject);
begin
  tmrDelayKey.Enabled := False;
end;

procedure TForm1.txtSearchAgreementCustomerEnter(Sender: TObject);
begin
  tmrDelayKey.Enabled := True;
  SearchComplete := True;
end;