idhttp get 的时候界面卡死情况

春华-秋实 2013-03-14 05:10:32
小弟在用idhttp 从服务器 get 一个文件的时候,界面不能移动,卡的非常死,请问什么方法可以解决这个问题,网上有看 用AntiFreeze 来解决,但是貌似添了也无效。求教,下面是code 在线等。
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CGAUGES"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdHTTP1Work(TObject *Sender, TWorkMode AWorkMode,
const int AWorkCount)
{
CGauge1->Progress = AWorkCount;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdHTTP1WorkBegin(TObject *Sender,
TWorkMode AWorkMode, const int AWorkCountMax)
{
Memo1->Lines->Add("Begin") ;
CGauge1->MaxValue = AWorkCountMax;
CGauge1->MinValue = 0;
CGauge1->Progress = 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdHTTP1WorkEnd(TObject *Sender,
TWorkMode AWorkMode)
{
Memo1->Lines->Add("End");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TStringStream *returnString=new TStringStream("");
Char* httpAddress = "http://unionupdate.kkpush.net/UnionUpdateService?";
Char* requestData = "param=<?xml%20version=\"1.0\"%20encoding=\"utf-8\"?><Request><RequestType>mobileVersion</RequestType><MobileVersionParams><OpType>getCurrentVersion</OpType><ClientVersion>";
Char* Version = "KABW960_CH.2.02.220";
Char* requestData2 = "</ClientVersion><RomSize></RomSize><UserName></UserName><SystemOuterVersion></SystemOuterVersion><FileType>img</FileType><CustomizationType>konka</CustomizationType>";
Char* requestData3 = "<Paramater1></Paramater1><Paramater2></Paramater2><Paramater3></Paramater3></MobileVersionParams><OtherParams></OtherParams></Request>";


StrCat(httpAddress,requestData);
StrCat(httpAddress,Version);
StrCat(httpAddress,requestData2);
StrCat(httpAddress,requestData3);
try
{
IdHTTP1->Get(httpAddress,returnString);
}
catch(...)
{
ShowMessage("服务器连接失败,请稍后重试");
this->Close();
}
String ss = returnString->DataString;
int i = ss.AnsiPos("KA"); /*获取最新的版本号,显示在Edit中*/
int j = ss.AnsiPos("</ResponseMessage>");
AnsiString version = ss.SubString(i,j-i);
int pos = ss.AnsiPos("http"); /*获取最新版本的下载地址,进行下载*/
int end = ss.AnsiPos("</DownloadUrl>");
AnsiString http = ss.SubString(pos,end-pos);
delete returnString;

TMemoryStream *myStream = new TMemoryStream();
try
{
IdHTTP1->Get(http,myStream);
}
catch(...)
{
ShowMessage("服务器连接失败,请稍后重试");
return;
}
myStream->SaveToFile("C://update.zip");
delete myStream;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdHTTP1Connected(TObject *Sender)
{
ShowMessage("connected");
}
//---------------------------------------------------------------------------
...全文
1119 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
春华-秋实 2013-03-28
  • 打赏
  • 举报
回复
搞定,谢谢大家了~
春华-秋实 2013-03-20
  • 打赏
  • 举报
回复
引用 15 楼 ccrun 的回复:
再说了,你在线程单元类中直接new一个IdHTTP对象使用,用完了直接delete了就行了,还在线程中去访问Form1上的IdHTTP1,这样的设计,不科学。
妖哥,谢谢了哈,已经改过来了,求教下,这样怎么去同步 Form1 中的进度条显示?
ccrun.com 2013-03-20
  • 打赏
  • 举报
回复
IdHTTP的Get是没有进度的,如果你想弄个进度条同步显示,用API函数URLDownloadToFile,具体实例请Google(记住,一定要用Google),或者用VCL中封装好的TDownLoadURL类,包含头文件ExtActns.hpp,代码自己Google,我只给提示。
ccrun.com 2013-03-19
  • 打赏
  • 举报
回复
再说了,你在线程单元类中直接new一个IdHTTP对象使用,用完了直接delete了就行了,还在线程中去访问Form1上的IdHTTP1,这样的设计,不科学。
ccrun.com 2013-03-19
  • 打赏
  • 举报
回复
一看你就木有细看Thread单元的提示,把访问VCL对象的代码放在一个函数中,然后用Synchronize来调用。
春华-秋实 2013-03-19
  • 打赏
  • 举报
回复
引用 12 楼 ccrun 的回复:
引用 11 楼 jinlu7611 的回复:引用 1 楼 ccrun 的回复:主线程中去Get肯定要阻塞主线程的,建议在另外的线程中执行。 妖哥,在线程外如何Get啊,我自己写了个,貌似不起作用,还是卡的死死的。求教~ 上代码look一下。
这是我自己写的一个简单的测试版本 主程序代码如下:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CGAUGES"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdHTTP1Work(TObject *Sender, TWorkMode AWorkMode,
const int AWorkCount)
{
CGauge1->Progress = AWorkCount;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdHTTP1WorkBegin(TObject *Sender,
TWorkMode AWorkMode, const int AWorkCountMax)
{
Memo1->Lines->Add("Begin");
CGauge1->MaxValue = AWorkCountMax;
CGauge1->MinValue = 0;
CGauge1->Progress = 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdHTTP1WorkEnd(TObject *Sender,
TWorkMode AWorkMode)
{
Memo1->Lines->Add("End");
CGauge1->Progress = 0;
pThread->Terminate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
pThread = new myThread(false);
}
//---------------------------------------------------------------------------
线程模块的程序如下:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "Unit1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall myThread::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall myThread::myThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall myThread::Execute()
{
//---- Place thread code here ----
Synchronize(DoWork);
}
//---------------------------------------------------------------------------
void __fastcall myThread::DoWork()
{
TStringStream *returnString=new TStringStream("");
Char* httpAddress = "http://unionupdate.kkpush.net/UnionUpdateService?";
//Char* httpAddress = "http://172.21.4.138:8080/UnionUpdate/UnionUpdateService?";
Char* requestData = "param=<?xml%20version=\"1.0\"%20encoding=\"utf-8\"?><Request><RequestType>mobileVersion</RequestType><MobileVersionParams><OpType>getCurrentVersion</OpType><ClientVersion>";
Char* Version ="KABW960_CH.2.02.220";
Char* requestData2 = "</ClientVersion><RomSize></RomSize><UserName></UserName><SystemOuterVersion></SystemOuterVersion><FileType>img</FileType><CustomizationType>konka</CustomizationType>";
Char* requestData3 = "<Paramater1></Paramater1><Paramater2></Paramater2><Paramater3></Paramater3></MobileVersionParams><OtherParams></OtherParams></Request>";
StrCat(httpAddress,requestData);
StrCat(httpAddress,Version);
StrCat(httpAddress,requestData2);
StrCat(httpAddress,requestData3);
try
{
Form1->IdHTTP1->Get(httpAddress,returnString);
}
catch(...)
{
ShowMessage("服务器连接失败,请稍后重试");
return;
}
String ss = returnString->DataString;
int pos = ss.AnsiPos("http");	 /*获取最新版本的下载地址,进行下载*/
int end = ss.AnsiPos("</DownloadUrl>");
AnsiString http = ss.SubString(pos,end-pos);
delete returnString;
TMemoryStream *myStream = new TMemoryStream();
try
{
Form1->IdHTTP1->Get(http,myStream);
}
catch(...)
{
ShowMessage("服务器连接失败,请稍后重试");
return ;
}
//获得当前路径
//Modified by konka zhangjinlu 20130311
//char* zipPath = ExtractFilePath(ParamStr(0)).c_str();
//StrCat(zipPath,"\update.zip");
//ShowMessage(zipPath);
// Modified by konka zhangjinlu 20130311
myStream->SaveToFile("C://update.zip");
delete myStream;
}
ccrun.com 2013-03-19
  • 打赏
  • 举报
回复
引用 11 楼 jinlu7611 的回复:
引用 1 楼 ccrun 的回复:主线程中去Get肯定要阻塞主线程的,建议在另外的线程中执行。 妖哥,在线程外如何Get啊,我自己写了个,貌似不起作用,还是卡的死死的。求教~
上代码look一下。
春华-秋实 2013-03-19
  • 打赏
  • 举报
回复
引用 1 楼 ccrun 的回复:
主线程中去Get肯定要阻塞主线程的,建议在另外的线程中执行。
妖哥,在线程外如何Get啊,我自己写了个,貌似不起作用,还是卡的死死的。求教~
hl0716 2013-03-16
  • 打赏
  • 举报
回复
正在做一个差不多的应用,比你的简单点,关注下

春华-秋实 2013-03-15
  • 打赏
  • 举报
回复
引用 8 楼 sololie 的回复:
用LS的方法吧,get post 这些常常都会很耗时,如果不用多线程你程序的用户体验将降到0点。
好的,我试试解决下。
sololie 2013-03-14
  • 打赏
  • 举报
回复
用LS的方法吧,get post 这些常常都会很耗时,如果不用多线程你程序的用户体验将降到0点。
dataxdata 2013-03-14
  • 打赏
  • 举报
回复
一般的情况可以把HTTP访问放在单独一个线程中,然后用一消息队列向这个线程发送指令,例如

void __fastcall MyThread::Execute() {
    Message msg;
    while ( MsgQueue.GetMessage(&msg) ) {
        switch ( msg.idType ) {
        case MSG_EXIT :
            goto exit;
        case MSG_HTTP_REQ :
            HttpSend((char*)msg.pvData);
            break;
        }
    }
exit :
    ......
}
void MyThread::HttpSend(const char *szReq) {
    ....
    http_get(....);
    .....
}
春华-秋实 2013-03-14
  • 打赏
  • 举报
回复
引用 4 楼 dataxdata 的回复:
在connect和recv的时候除了等待没有别的办法,所以最好还是放在单独的线程中去执行
有没有简单的代码示例,思路到了也行。。
春华-秋实 2013-03-14
  • 打赏
  • 举报
回复
引用 3 楼 sololie 的回复:
非要主线程中又不想卡界面那自然就是Application->ProcessMessages()了。 耗时的任务还是得分线程去做。
这个是如何使用?有能写个示意的code 吗?
dataxdata 2013-03-14
  • 打赏
  • 举报
回复
在connect和recv的时候除了等待没有别的办法,所以最好还是放在单独的线程中去执行
sololie 2013-03-14
  • 打赏
  • 举报
回复
非要主线程中又不想卡界面那自然就是Application->ProcessMessages()了。 耗时的任务还是得分线程去做。
春华-秋实 2013-03-14
  • 打赏
  • 举报
回复
引用 1 楼 ccrun 的回复:
主线程中去Get肯定要阻塞主线程的,建议在另外的线程中执行。
我在网上看过,好像都是建议在线程中执行的,除了这个,有没有其他的方法?
ccrun.com 2013-03-14
  • 打赏
  • 举报
回复
主线程中去Get肯定要阻塞主线程的,建议在另外的线程中执行。

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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