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?似乎对我没有任何好处。如果你不维护线程的引用,你就不能在关机时加入它。