Multithreading Delphi线程[查看我的代码]

Multithreading Delphi线程[查看我的代码],multithreading,delphi,Multithreading,Delphi,所以我的代码是这样的: 线程中的下载页面 解析页面 发送到主线程 所有这些都是在关键部分和后期消息上完成的。 如果有人能回顾它,修复它,改变它,或者做任何其他可以让它更好的事情 Main VCL form : unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OverbyteIcsWndControl,

所以我的代码是这样的:

  • 线程中的下载页面
  • 解析页面
  • 发送到主线程
  • 所有这些都是在关键部分和后期消息上完成的。 如果有人能回顾它,修复它,改变它,或者做任何其他可以让它更好的事情

    Main VCL form :
    
        unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, OverbyteIcsWndControl, OverbyteIcsHttpProt, StdCtrls,Unit2;
    const
      WM_DATA_IN_BUF = WM_APP + 1000;
    
    type
      TForm1 = class(TForm)
        HttpCli1: THttpCli;
        Button1: TButton;
        ListBox1: TListBox;
        Memo1: TMemo;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        FStringSectInit: boolean;
        FGoogle: TGoogle;
        FStringBuf: TStringList;
        procedure HandleNewData(var Message: TMessage); message WM_DATA_IN_BUF;
      public
         StringSection: TRTLCriticalSection;
        property StringBuf: TStringList read FStringBuf write FStringBuf;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if not FStringSectInit then
      begin
        InitializeCriticalSection(StringSection);
        FStringBuf := TStringList.Create;
        FStringSectInit := true;
        FGoogle := TGoogle.Create(true);
        SetThreadPriority(FGoogle.Handle, THREAD_PRIORITY_BELOW_NORMAL);
        try
          FGoogle.StartNum := 8;
        except
          on EConvertError do FGoogle.StartNum := 2;
        end;
        FGoogle.Resume;
      end;
    end;
    
    procedure TForm1.HandleNewData(var Message: TMessage);
    var i:integer;
    begin
      if FStringSectInit then
      if listbox1.Items.Count<10 then
      begin
        EnterCriticalSection(StringSection);
        for i:=0 to 5 do
        if length(fstringbuf.Text)>10 then
        begin
        listbox1.Items.Add(FStringBuf.Strings[i]);
        end
        else
        FStringBuf.Clear;
        LeaveCriticalSection(StringSection);
        {Now trim the Result Memo.}
      end
      else
      begin
        with FGoogle do
        begin
          Terminate;
          WaitFor;
          Free;
        end;
       FGoogle := nil;
        FStringBuf.Free;
        FStringBuf := nil;
        DeleteCriticalSection(StringSection);
        FStringSectInit := false;
      end;
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    if listbox1.Items.Count>80 then
    end;
    
    end.
    
    主要VCL表格:
    第一单元;
    接口
    使用
    窗口、消息、系统工具、变体、类、图形、控件、窗体、,
    对话框,OverbytecsWndControl,OverbytecsHttpProt,StdCtrls,Unit2;
    常数
    WM_DATA_IN_BUF=WM_APP+1000;
    类型
    TForm1=类(TForm)
    HttpCli1:THttpCli;
    按钮1:t按钮;
    ListBox1:TListBox;
    备忘录1:TMemo;
    按钮2:t按钮;
    程序按钮1点击(发送方:ToObject);
    程序按钮2点击(发送者:对象);
    私有的
    FStringSectInit:布尔值;
    FGoogle:TGoogle;
    FStringBuf:TStringList;
    过程HandleNewData(变量消息:TMessage);消息WM_DATA_IN_BUF;
    公众的
    StringSection:TRTLCriticalSection;
    属性StringBuf:TStringList读取FStringBuf写入FStringBuf;
    结束;
    变量
    表1:TForm1;
    实施
    {$R*.dfm}
    程序TForm1.按钮1单击(发送方:TObject);
    开始
    如果不是FStringSectInit,则
    开始
    初始化CriticalSection(StringSection);
    FStringBuf:=TStringList.Create;
    FStringSectInit:=真;
    FGoogle:=TGoogle.Create(true);
    设置线程优先级(FGoogle.Handle,线程优先级低于正常值);
    尝试
    FGoogle.StartNum:=8;
    除了
    在EConvertError上,do FGoogle.StartNum:=2;
    结束;
    FGoogle.恢复;
    结束;
    结束;
    过程TForm1.HandleNewData(变量消息:TMessage);
    varⅠ:整数;
    开始
    如果是FStringSectInit,则
    如果列表框1.Items.Count10,则
    开始
    listbox1.Items.Add(FStringBuf.Strings[i]);
    结束
    其他的
    FStringBuf.Clear;
    临界断面(纵断面);
    {现在修剪结果备忘录。}
    结束
    其他的
    开始
    用FGoogle do
    开始
    终止
    等待;
    自由的
    结束;
    FGoogle:=零;
    FStringBuf.Free;
    FStringBuf:=零;
    删除临界截面(StringSection);
    FStringSectInit:=false;
    结束;
    结束;
    程序TForm1.按钮2单击(发送方:TObject);
    开始
    如果listbox1.Items.Count>80,则
    结束;
    结束。
    
    而线程:

    unit Unit2;
    
    interface
    
    uses
      Classes,Windows,IDHTTP, OverbyteIcsWndControl, StdCtrls,OverbyteIcsHttpProt,SysUtils,Dialogs;
    
    type
      TGoogle = class(TThread)
      private
    google:TStringList;
        Upit:string;
        Broj:integer;
        Buffer : TStringList;
      protected
        procedure parsegoogleapi;
        procedure SkiniSors;
        procedure Execute; override;
      public
        property StartNum: integer read Broj write Broj;
      end;
    
    implementation
    uses unit1,StrUtils;
    
    function ExtractText(const Str, Delim1, Delim2: string; PosStart: integer; var PosEnd: integer): string;
    var
     pos1, pos2: integer;
    begin
        Result := '';
        pos1 := PosEx(Delim1, Str, PosStart);
        if pos1 > 0 then
        begin
        pos2 := PosEx(Delim2, Str, pos1 + Length(Delim1));
        if pos2 > 0 then
        begin
          PosEnd := pos2 + Length(Delim2);
          Result := Copy(Str, pos1 + Length(Delim1), pos2 - (pos1 + Length(Delim1)));
    end;
    end;
    end;
    function ChangeString(const Value: string; replace:string): string;
    var i: Integer;
    begin
        Result := '';
        for i := 1 to Length(Value) do
        if Value[i] = ' ' then
        Result := Result + replace
        else
        Result := Result + Value[i]
    end;
    
    (*Ovo je procedura za skidanje sorsa*)
    
    procedure TGoogle.SkiniSors;
    var
    HttpCli1 : THttpCli;
    criter:string;
    
    begin
    
    HttpCli1:=THttpCli.Create(nil);
    google:=TStringList.Create;
    criter:= ChangeString(Upit,'%20');
    
    With HttpCli1 do begin
        URL            := 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&start=' + inttostr(broj) + '&rsz=large&q=index.php';
        RequestVer     := '1.1';
        RcvdStream := TMemoryStream.Create;
        try
            Get;
        except
            ShowMessage('There has been an error , check your internet connection !');
            RcvdStream.Free;
            Exit;
        end;
    
    RcvdStream.Seek(0,0);
    google.LoadFromStream(RcvdStream);
    RcvdStream.Free;
     broj:=broj+8;
    ParseGoogleApi;
    end;
    end;
    
    procedure TGoogle.ParseGoogleApi;
    var Pos: integer;
        sText: string;
    begin
    Buffer:= TStringList.Create;
      sText := ExtractText(google.Text, '"url":"', '","visibleUrl"', 1, Pos);
      while sText <> '' do
      begin
        buffer.Add(sText);
    
        sText := ExtractText(google.Text, '"url":"', '","visibleUrl"', Pos, Pos);
      end;
    end;
    
    
    procedure TGoogle.Execute;
    var
      CurrentNum: integer;
      i:integer;
    
    begin
    
      CurrentNum := Broj;
      while not terminated do
      begin
      skinisors;
          EnterCriticalSection(Form1.StringSection);
          for i:=0 to 5 do                        begin
          Form1.StringBuf.Add(buffer.strings[i]);
          end;
          LeaveCriticalSection(Form1.StringSection);
          PostMessage(Form1.Handle, WM_DATA_IN_BUF, 0, 0);
    
        end;
    
    
    end;
    end.
    
    单元2;
    接口
    使用
    类、Windows、IDHTTP、OverbytecsWndControl、StdCtrls、OverbytecsHttpProt、SysUtils、对话框;
    类型
    TGoogle=class(TThread)
    私有的
    谷歌:TStringList;
    Upit:字符串;
    Broj:整数;
    缓冲区:TStringList;
    受保护的
    程序分析;
    皮肤剥脱术;
    程序执行;推翻
    公众的
    属性StartNum:整数读取Broj写入Broj;
    结束;
    实施
    使用unit1、StrUtils;
    函数ExtractText(const Str,Delim1,Delim2:string;PosStart:integer;var PosEnd:integer):string;
    变量
    pos1,pos2:整数;
    开始
    结果:='';
    pos1:=PosEx(Delim1,Str,PosStart);
    如果pos1>0,则
    开始
    pos2:=PosEx(Delim2,Str,pos1+长度(Delim1));
    如果pos2>0,则
    开始
    PosEnd:=pos2+长度(m2);
    结果:=拷贝(Str,pos1+长度(Delim1),pos2-(pos1+长度(Delim1));
    结束;
    结束;
    结束;
    函数ChangeString(常量值:string;替换:string):string;
    varⅠ:整数;
    开始
    结果:='';
    对于i:=1到长度(值)do
    如果值[i]='',则
    结果:=结果+替换
    其他的
    结果:=结果+值[i]
    结束;
    (*Ovo je procedura za skidanje sorsa*)
    程序TGoogle.SkiniSors;
    变量
    HttpCli1:THttpCli;
    生物:弦;
    开始
    HttpCli1:=THttpCli.Create(nil);
    google:=TStringList.Create;
    criter:=ChangeString(Upit,'%20');
    使用HttpCli1开始
    网址:='http://ajax.googleapis.com/ajax/services/search/web?v=1.0&start=“+inttostr(broj)+”&rsz=large&q=index.php”;
    请求者:='1.1';
    RcvdStream:=TMemoryStream.Create;
    尝试
    得到;
    除了
    ShowMessage('出现错误,请检查您的internet连接!');
    RcvdStream.Free;
    出口
    结束;
    RcvdStream.Seek(0,0);
    LoadFromStream(RcvdStream);
    RcvdStream.Free;
    broj:=broj+8;
    帕斯古格里皮;
    结束;
    结束;
    程序TGoogle.ParseGoogleApi;
    var-Pos:整数;
    sText:字符串;
    开始
    Buffer:=TStringList.Create;
    sText:=ExtractText(google.Text,“url”:“,”,“visibleUrl”,1,Pos);
    而sText“”可以
    开始
    buffer.Add(sText);
    sText:=ExtractText(google.Text,“url”:“,”,“visibleUrl”,Pos,Pos);
    结束;
    结束;
    程序TGoogle.Execute;
    变量
    CurrentNum:整数;
    i:整数;
    开始
    CurrentNum:=Broj;
    虽然没有终止
    开始
    剥皮者;
    EnterCriticalSection(格式1.StringSection);
    对于i:=0到5,开始
    Form1.StringBuf.Add(buffer.strings[i]);
    结束;
    离开临界断面(格式1.纵断面);
    PostMessage(Form1.Handle,WM_DATA_IN_BUF,0,0);
    结束;
    结束;
    结束。
    
    所以我想知道,当页面超时或用户断开连接时,如何停止线程。。这样线程就可以正确终止


    我想启动这个线程的3个实例,每个实例都应该访问关键部分,取一个link ex link[I],其中I是整数值,该整数值由当时拥有关键部分所有权的线程递增。谢谢

    给你的线程一个构造函数,在该构造函数中设置
    FreeOnTerminate:=True


    在线程的execute方法中,您可以调用
    Terminate页上超时或断开连接。

    属于页上。对于损坏的代码也是如此。发布一个特定的问题和一个相关的代码片段,该代码的格式肯定会损坏。你能解释为什么这会是一个改进吗?这是对问题元素
    的响应,所以我想知道当页面超时或用户断开连接时,如何停止线程。。因此线程可以正确终止。
    但为什么要FreeOnTerminate?似乎对我没有任何好处。如果你不维护线程的引用,你就不能在关机时加入它。