正在写一个小程序,用来模拟google maps或者Yahoo maps的卫片浏览功能。
下载采用了CInternetSession中的OpenURL函数来进行操作。
采用了多线程下载的方式,同时下载 5*5 的图像。多线程采用MFC的消息队列进行同步,就是说每个线程下载完毕后向框架发送一个消息。
基本的功能是实现了,不过有两个致命的问题,请教一下:)第一个问题:很多情况下,在没有下载完当前所有图像的时候,用户就会进行操作,这样就需要强行关闭正在下载中的线程,而由于采用了发送消息的方式,在线程中分配了内存,TerminateThread会导致内存的泄漏。有什么办法可以关闭线程,又保证不泄漏内存呢?第二个问题:其实是在上一个问题的基础上的,同样是如果用户在没有下载完当前图像的时候执行操作,会出现OpenURL函数没有反应的情况。我进入到OpenURL函数中,发现执行到InternetOpenUrl函数后,OpenURL函数就没有反应了。这是什么原因呢?是因为强制关闭线程的时候,原有的CInternetSession没有关闭?还是因为连接到服务器的CInternetSession太多了?这些原因都是我瞎猜的,因为OpenURL函数也没有返回什么错误代码,仅仅是完全没有反应了。所以恳请解答!不好意思,我对网络编程不熟悉,上面的问题不是很专业,请高手解答一下,多谢!

解决方案 »

  1.   

    >无法和下载线程进行交互
    没用过Windows同步内核对象?
      

  2.   

    汗,我就是想避免使用同步,才使用windows消息队列来进行同步的
    您的意思是只有使用同步内核对象才能完成这个要求吗?
    谢!
      

  3.   

    给你几个同步的API封装类:  事件
      
    给一个好用的类
    #ifndef _CEVENT_SYNCHRONIZATION_H_
    #define _CEVENT_SYNCHRONIZATION_H_#include <cassert>class CEventSync  
    {
    public:CEventSync(HANDLE *pHandle)
    {
       assert(pHandle);
           m_pHandle=pHandle;
           DWORD dwRet=WaitForSingleObject(*m_pHandle,INFINITE);
     。。      
           ResetEvent(*m_pHandle);
           assert(dwRet==WAIT_OBJECT_0);       if(dwRet!=WAIT_OBJECT_0)
       {
    。。
       }
    。。}virtual ~CEventSync()
    {
       SetEvent(*m_pHandle);
    }
    private:
        HANDLE * m_pHandle;  
    };#endif使用方法:HANDLE hEvent=CreateEvent(NULL,TRUE,TRUE,"");
    CEventSync  EventSync(&hEvent); 自动同步,
    如果有两个线程,同时在hEvent上使用EventSync(&hEvent);
    那么其中一个会阻塞在EventSync(&hEvent);上,直到另一个结束。
    简单易用
      

  4.   

    class CAutoCodeLock;/*
     *  临界区封装基类.
     */
    class CBaseCritSection
    {
       friend class CAutoCodeLock;
    protected:
       virtual void Lock()=0;
       virtual void UnLock()=0;
    };/*___________________________________________
     *                                          * 
     *  临界区封装类.                           * 
     *__________________________________________*/
    class CCritSection : public CBaseCritSection
    {
        friend class CAutoCodeLock; 
    public:CCritSection()
    {
       InitializeCriticalSection(&m_CritSection);
    }~CCritSection()
        {
        DeleteCriticalSection(&m_CritSection);
    }private:    void Lock()
    {
        EnterCriticalSection(&m_CritSection);
    }    void UnLock()
    {
        LeaveCriticalSection(&m_CritSection);
    }CRITICAL_SECTION m_CritSection;
    };
    /*_________________________________________________
     *                                                *
     *   临界区使用类                                 *
     *________________________________________________*/
    class CAutoCodeLock  
    {
    public:CAutoCodeLock(CBaseCritSection * pCritSection)
    {
       assert(pCritSection);
       m_pCritSection=NULL;
       if(pCritSection!=NULL)
       {
       m_pCritSection=pCritSection;
           m_pCritSection->Lock();
       }
    }
    virtual ~CAutoCodeLock()
    {
       if(m_pCritSection!=NULL)
       {
          m_pCritSection->UnLock();
      m_pCritSection=NULL;
       }
    }private:
        CBaseCritSection * m_pCritSection;
    };
    使用方法:#include "...."
    class xxxx
    {
    .....................
    .....................
    private:
    CCritSection m_CritSec;
    };void xxxx::fucn()
    {CAutoCodeLock  AutoLock(&m_CritSec);
    }
      

  5.   

    TerminateThread本身就是一个容易引起内存泄露的函数,最好采用同步EVENT事件通知结束
    看看MSDN怎么说:TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination.
      

  6.   


     用专业的 糖果下载Activex吧, 任何时候都能退出: http://www.languangav.com/soft/product_down.htm
      

  7.   

    这里有个跨平台的下载库,支持HTTP,FTP,HTTPS,多线程下载,还能在手机上跑,挺强的,你可以参考下
    http://www.easygeteasy.com
      

  8.   

     点量Http、FTP多线程断点续传下载组件(下载DLL)的开发目的是让用户可以无需关心Http/FTP协议的具体细节,只需要几十行甚至几行代码,便可以实现一个功能完善的Http/FTP下载软件。点量Http/FTP下载组件(DLL)支持多线程、断点续传、显示详细下载过程、自动查找镜像网址、支持代理传输等完善的功能。     点量Http、FTP下载内核源码使用高效的c++代码编写,提供标准的动态链接库(DLL),可供C/C++、Delphi、C#、Java、VB等语言和各常用开发环境调用,让您完全像调用系统API一样的调用。     点量Http/FTP组件的功能简介:标准Http和FTP下载支持:完全标准的Http和FTP协议支持,内部通过网址自动区分是Http还是FTP下载。 
    极速下载(2.0以后版本):超越国内绝大多数下载软件的下载速度。新版内核在2M ADSL的环境下下载,有些文件的速度可以达到1400K字节/秒以上,超过了带宽的极限。下载速度可以用极速形容。 
    多线程传输:可以将文件自动分块,并采用多线程下载。并可自由设置线程数目。 
    断点续传:点量Http/FTP有优秀的断点续传支持,每次启动自动从上次下载的位置开始,不需要重复下载。 
    提供详细的下载详情接口(2.0以后版本):可以看到整个下载过程的步骤,比如开启了多少线程、服务器的应答过程、错误信息等。 
    支持多种高级设置:设置线程数目、磁盘缓存大小、搜索镜像服务器的详细参数设置、下载文件完成后同步文件为服务器上的文件时间、下载过程中可以自定义文件临时后缀、未完成的文件设为隐藏属性。 
    支持磁盘缓存:点量Http/FTP下载DLL支持设置磁盘缓存,减少对磁盘的读写,并提升下载速度。 
    支持设置Refer:点量Http/FTP下载组件支持设置下载时的Refer,以便可以绕过一些防盗链的网站,直接下载内容。 
    限速功能:点量Http/FTP下载组件可方便的设置下载限速。 
    多种磁盘分配方式:点量Http/FTP下载组件支持预分配和边下载边分配两种磁盘方式,满足多种下载需求。 
    自动搜索镜像加速:点量Http/FTP内置了镜像搜索功能,在下载文件的同时,会自动搜索哪些其它网站还有这个文件,自动从其它网址下载加速。 
    可提供源码:支付一定的费用,便可以获得全部的点量Http/FTP下载组件的源代码,免除您的所有后顾之忧。 
    良好的服务:作为点量软件旗下的软件,可享受到点量软件的优秀服务,我们的服务让您如同拥有一个称心的专业员工。点量Http/FTP 下载组件可以适用于任何Http和FTP下载的领域,让您可以在1天内完成一个完整的Http下载软件的全部功能。比如,您可以用于产品的升级、文件的下载和传输等。 
    点量Http/FTP内核可以为您带来:
    1、大大节省您的开发成本:了解Http和FTP的协议,再去编码、测试,即使对于一个非常有经验的开发人员来说,也需要较长期的时间,此间耗费的人力资源成本和管理成本可谓不少。而使用点量Http/FTP,您就不需要从制造轮子开始制造您的汽车,将注意力集中于车的设计而不是基础设备的建设。何况我们的产品性能是如此优越!2、强有力的技术支持:作者长期从事下载技术的研发,所提供的技术支持相当于您雇佣了一位具有丰富经验,无需从头学习的开发人员,可以在您的系统建设过程中为您提供整体系统架设的意见。如果您是个人作为非商业目的使用,您可以自由、免费的使用点量Http/FTP下载组件内核库和演示程序,也期待收到您反馈的意见和建议;如果您是商业使用,那么您需要联系作者申请产品的商业授权。-----------------------------------------------------------------------------------------------------------------------
    点量软件官方地址:http://www.dolit.cn          http://hi.baidu.com/dlbtsoft   点量Http/FTP内核SDK下载地址:http://hi.baidu.com/dlbtsoft/blog/item/09fa66d15a258d89a1ec9c6f.html。