Function  FindLrc(p: Pointer): DWORD; stdcall;
var
  ss: UTF8String;
  Reg: TPerlRegEx;
  i: Integer;
  ResultList1: TStrings;
  begin
  EnterCriticalSection(MyCs); //进入临界区
  ResultList1 := TStringList.Create;
  Reg := TPerlRegEx.Create();
  Reg.Options := [preMultiLine, preCaseLess]; // 重要:设置匹配模式:多行
  try
  ss := Form1.QQEdit2.Text;
  if Trim(ss) <> '' then
  begin
  if SuperLrcSearch=True then
  begin
  for i := 0 to Length(Lrcrecord) - 1 do
  begin
  Reg.Subject :=Lrcrecord[i].Content+Lrcrecord[i].Name;
  Reg.RegEx :='(.*?)('+ss+')(.*?)$';
  if Reg.Match then ResultList1.Add(Lrcrecord[i].Name+'【'+reg.MatchedText+'】');
  end;
  end
  else
  begin
  for i := 0 to Form1.resultlist.Count - 1 do
  begin
  Reg.Subject := Form1.resultlist.Strings[i];
  Reg.RegEx :='^'+ss;
  if  Reg.Match then ResultList1.Add(Form1.resultlist.Strings[i]);
  end;
  end;
  Form1.lst1.Items.Clear;
  Form1.lst1.Items.AddStrings(ResultList1);
    // LabeledEdit1.EditLabel.Caption:='共'+inttostr(lst1.Items.Count) +'首歌词->搜索:';
  Form1.MyShape1.Text := '共' + inttostr(Form1.lst1.Items.Count) + '首歌词->搜索:';
  end;
  finally
  Reg.Free;
  ResultList1.Free;
  LeaveCriticalSection(MyCs); //离开临界区
  CloseHandle(hThread);
  end;
result:=0;
end;procedure TForm1.LabeledEdit1Change(Sender: TObject);
var
  ID:DWORD;
begin
hThread:=CreateThread(nil, 0, @Findlrc, nil, 0, ID);
//TThread.CreateAnonymousThread(Findlrc).Start;
end;
好像很不合理,每次都创建销毁线程。
本来不写在线程里的,但是Lrcrecord记录量大了查询就慢会让窗体假死,写在线程里就不会了。
但是每执行一次内存占用就多几百KB到最后程序直接自动关闭了。

解决方案 »

  1.   

    1)佩服。
    2)理解Delphi的主线程,和线程的区别
    3)理解为什么使用临界区
    4)想清楚为什么要每次创建线程
      

  2.   

    啊!是写的很烂啊,对线程不是很理解
    用临界区是因为放在Change事件里面,就是要保护起来,不然返回的数据就不对了
    我也不想每次都创建,但是不知道要怎么改才可以,就是对Edit的死循环判断,其实不用写线程,放在主线程里就可以的,但是数据量大了,执行查询就很慢,会假死。
    好吧,我好像知道要怎么做了。
      

  3.   

    再帮我看看这个 LrcRecord这个记录类型,这个是加载的数据量很大,而且要到程序退出才会释放,这样影响大不大?这个数据不会存储在本地,是把歌名,歌词全部记录进去了,方便查询!
      

  4.   

    假死?在你的循环里加上一句
    Application.ProcessMessages;
      

  5.   

    procedure TForm1.LabeledEdit1Change(Sender: TObject);
    var
      ID:DWORD;
    begin
    hThread:=CreateThread(nil, 0, @Findlrc, nil, 0, ID);
    //TThread.CreateAnonymousThread(Findlrc).Start;
    end;
    这样做不大才怪,线程预先创建好,你要查询歌词的时候向线程发消息就可以了。至于线程的消息处理查下网上很多这方面的介绍。