使用Idhttp.get('') 造成假死(堵塞),请问线程idhttp怎么才能做到不出错?

xiaoruirui03 2010-04-09 01:11:02
type
 TMyThread = class(TThread)
 protected
  procedure Execute; override;
 end;
procedure TMyThread.Execute;
var
 i: Integer;
begin
 FreeOnTerminate := True; {这可以让线程执行完毕后随即释放}
 for i := 0 to 500000 do
 begin
sleep(500);
form1.Memo1.text := form1.idhttp1.get('网站地址');
 end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
 TMyThread.Create(False);
end;



在主线程idhttp get 一个地址,会卡1秒,如果那个地址大一点会卡2-3秒,
我需要循环的下载..老是卡不是办法..

然后听说用线程可以解决.于是找到了如上代码,
可以,成功了.主线程不卡了,但是运行久了就出错..
听前辈和网上说直接在线程用控件就会出错.即使当时不错,长了就出错。.


请问怎么解决?

用Synchronize? 不会..用了Synchronize是调用一个过程,然后调用的还是主线程里的控件?
那不还是卡...

求方法,代码,

...全文
704 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
menghl 2010-07-17
  • 打赏
  • 举报
回复
用Synchronize界面确实很卡.
SQLDebug_Fan 2010-04-11
  • 打赏
  • 举报
回复
在线程中访问主线程的VCL是有极大风险的,你的这个程序,完全可以在子线程中创建TIDHTTP,收到内容后发消息给主线程通知,具体代码:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP;

const
WM_WebUpdate = WM_USER + 1000;
type
TForm1 = class(TForm)
btn1: TButton;
mmo1: TMemo;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure WMWebUpdate(var AMessage: TMessage); message WM_WebUpdate;
end;

TMyThread = class(TThread)
private
FRunType: Integer;
procedure Procedure0;
procedure Procedure1;
protected
procedure Execute; override;
public
property RunType: Integer read FRunType write FRunType;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

procedure TMyThread.Execute;
begin
inherited;
case FRunType of
0: Procedure0;
1: Procedure1;
end;
end;

procedure TMyThread.Procedure0;
var
IDHttp: TIdHTTP;
sWeb: string;
begin
IDHttp := TIdHTTP.Create(nil);
try
sWeb := IDHttp.Get('http://topic.csdn.net/u/20100409/13/fec3bb35-2dc2-431a-950e-c8f20e8b44c8.html?6345');
SendMessage(Form1.Handle, WM_WebUpdate, Integer(PChar(sWeb)), 0);
finally
IDHttp.Free;
end;
end;

procedure TMyThread.Procedure1;
begin
//类别1执行代码
end;

procedure TForm1.btn1Click(Sender: TObject);
var
MyThread0, MyThread1: TMyThread;
begin
MyThread0 := TMyThread.Create(True);
MyThread0.FreeOnTerminate := True;
MyThread0.RunType := 0;
MyThread0.Resume;

MyThread1 := TMyThread.Create(True);
MyThread1.FreeOnTerminate := True;
MyThread1.RunType := 1;
MyThread1.Resume;
end;

procedure TForm1.WMWebUpdate(var AMessage: TMessage);
var
pWeb: PChar;
begin
pWeb := PChar(AMessage.WParam);
mmo1.Lines.Add(pWeb);
end;

end.

在我本机调试通过
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!
kaixindzl 2010-04-10
  • 打赏
  • 举报
回复
更正一下上面的线程函数内的代码:

procedure Tget.Execute;
var htp: TIdHTTP ;
begin
while not Terminated do
begin
try
if str <> '' then str := '' ;
htp := TIdHTTP.Create(nil) ;
str := htp.Get('http://topic.csdn.net/u/20100409/13/fec3bb35-2dc2-431a-950e-c8f20e8b44c8.html?62489') ;
FreeAndNil(htp);
Synchronize(synWrite);
except
//ShowMessage('出错了..');
if htp <> nil then FreeAndNil(htp);
end;
Sleep(500);
end;
end;
kaixindzl 2010-04-10
  • 打赏
  • 举报
回复

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, idhttp, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

Tget = class(TThread)
private
str: string ;
count: DWORD ;
protected
procedure Execute ; override ;
public
procedure synWrite ;
end;

var
Form1: TForm1;
implementation

{$R *.dfm}

{ Tget }

procedure Tget.Execute;
var htp: TIdHTTP ;
begin
htp := TIdHTTP.Create(nil) ;
while not Terminated do
begin
try
if str <> '' then str := '' ;
str := htp.Get('http://topic.csdn.net/u/20100409/13/fec3bb35-2dc2-431a-950e-c8f20e8b44c8.html?62489') ;
Synchronize(synWrite);
except
end;
Sleep(500);
end;
htp.Free ;
end;

procedure Tget.synWrite;
begin
Form1.Memo1.Text := str ;
Inc(count) ;
Form1.Caption := IntToStr(count) ; //查看线程是否意外中止.
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Tget.Create(False) ;
end;

end.

kfcoffe 2010-04-09
  • 打赏
  • 举报
回复
........................
mjp1234airen4385 2010-04-09
  • 打赏
  • 举报
回复
这是我以前写的一个例子,你可以参考线程部分,使用回调函数完成。
参考
wintergoes 2010-04-09
  • 打赏
  • 举报
回复
你目前这种方式和不用线程是一样的,线程一点作用都没起到。
wintergoes 2010-04-09
  • 打赏
  • 举报
回复
在线程里动态创建IDHTTP


type
 TMyThread = class(TThread)
 protected
  procedure Execute; override;
Private
FIDhttp: TIdhttp;
public
Constructor Create(CreateSuspended: BOolean);
Destructor Destroy; override;
 end;

// create
begin
inherited create(createsuspended);
FIDhttp := TIDhttp.create(nil);
end;

// destroy
begin
FIdhttp.Free;
end;

procedure TMyThread.Execute;
var
 i: Integer;
begin
 FreeOnTerminate := True; {这可以让线程执行完毕后随即释放}
 for i := 0 to 500000 do
 begin
sleep(500);
form1.Memo1.text := form1.idhttp1.get('网站地址');
 end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
 TMyThread.Create(False);
end;


xiaoruirui03 2010-04-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sanguomi 的回复:]
你可以把IDHTTP的连接时间设长点
我都是自己写SOCKET去实现HTTP的操作
[/Quote]

谢谢建议,

但是我遇到问题就是不停的GET呵呵,线程弄好了估计就解决了








用了线程不卡了,就是长了会出错.往上说什么什么同步什么什么Synchronize
sanguomi 2010-04-09
  • 打赏
  • 举报
回复
你可以把IDHTTP的连接时间设长点
我都是自己写SOCKET去实现HTTP的操作

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧