基于FormView的一个可视化程序,点击某按钮以后遍历文件夹,当找到一个文件时,就启动一个副线程并在这个线程中执行某些操作,代码如下:void CXXXView::DelDir(const CString &strDirName)
{    CString strTarget = strDirName + "\\*.*";

    CFileFind finder;
    BOOL bWorking = finder.FindFile((LPCTSTR)strTarget);    while (bWorking)
    {
bWorking = finder.FindNextFile();
if(finder.IsDots())
continue;
m_strFileName=finder.GetFilePath();
if(finder.IsDirectory())
{//递归调用
    DelDir(m_strFileName);
}
else
{//启动线程
    AfxBeginThread(FileDelThread,(void *)this);
        }
     }
}
m_strFileName是CXXXView的一个成员变量,通过线程传递的this指针就可以在线程里访问这个变量线程函数代码如下:UINT CXXXView::FileDelThread(void * param)
{
    CXXXView * pView=(CXXXView *)param;
    CString strFileName=pView->m_strFileName;
    //对文件的操作用打印来代替,因为对文件操作要不断读写硬盘,所以启用线程,而不是在主线程的递归程序中完成
    AfxMessageBox(strFileName);}
我建立一个文件夹A,A文件夹下面有文件1.txt和子文件夹B,子文件夹B下面有文件2.txt
执行程序却不能得到遍历的结果,两次打印的都是2.txt,这是什么原因,是不是两个子线程打印消息的时候m_strFileName已经更新为2.txt了呢?我也尝试传递文件名到线程中,这样是可以的,但是this指针就不能传递进来了,因为我要引用CXXXView里的一个CListBox对象用以显示遍历文件的情况,所以就有些矛盾了,可以传文件名,但是得不到this指针,传了this指针之后,又发现遍历文件有问题,怎么解决呢?

解决方案 »

  1.   

    试试改为这样:void CXXXView::DelDir(CString strDirName)
    {
        CFileFind finder;
        BOOL bWorking = finder.FindFile(strDirName + _T("\\*.*"));    while (bWorking)
        {
        bWorking = finder.FindNextFile();    if (finder.IsDots())
            continue;    if (finder.IsDirectory())
        {
            //递归调用
            DelDir(finder.GetFilePath());
        }
        else
        {
           //启动线程
            AfxBeginThread(FileDelThread, (LPCTSTR)finder.GetFilePath());
         }
    }
      

  2.   

    //使用线程不能传递局部变量,试试改为这样:TCHAR *pszPath = _tcsdup(finder.GetFilePath()); //复制文件路径。AfxBeginThread(FileDelThread, pszPath);//在线程中使用 free 删除为文件路径分配的内存。
      

  3.   

    你可以把文件名和this指针作为一个结构体等,然后再转换为线程函数的LPVOID传递进去线程
      

  4.   

    LS的这样我试过,是在线程里做这样的一个强制转换吗?(CString *)str=(CString *)param;但是打印str好像是空的,另外这样也有问题,我还是得不到this指针,怎么显示在listbox中
      

  5.   

    this指针和你的文件名作为一个结构体(比如:MyInfo的两个元素,,
    线程中?(MyInfo*)pInfo=(MyInfo*)param;
    pInfo->来访问this 指针和文件名两个变量...
      

  6.   

    参考你的方法,定义了一个结构体
    struct stParam
    {
    CListBox * box;
    CString str;
    };启动线程前这样改
    stParam *pstParam=(stParam *)malloc(sizeof(struct stParam));
    pstParam->box=&m_listbox;
    pstParam->str=m_strFileName;
    AfxBeginThread(FileDelThread,(void *)pstParam);线程中改为
    stParam *ptheParam=(stParam *)param;
    AfxMessageBox(ptheParam->str);
    free(ptheParam);
    还是有错,是哪里出了问题呢
      

  7.   

    自定义一个结构,结构中定义CXXXView*和CString两个变量,分配用与传递视图指针和文件路径,每次创建线程之前用new分配结构,线程中delete。
      

  8.   

    用new和delete,不能用malloc和free,因为CString是C++对象,需要构造。
      

  9.   

    没错,按照你的思路,你想在主线程中修改某个参数,并在工作线程中引用此参数
    多个线程同时工作的时候需要考虑并发与同步:建议你在主线程中定义成员变量:vector<string> colName;
    并增加对应的互斥对象CRITICAL_SECTION m_csName;
    用法: 
    主线程的构造函数中添加:InitializeCriticalSection(&m_csName);
    析构函数中: DeleteCriticalSection (&m_csName);
    每次遍历到一个文件: 
        EnterCriticalSection(&m_csName);
        colName.push_bach(strFileName);
        LeaveCriticalSection(&m_csName);
    在工作线程中获取文件名:
        string strFileName;
        EnterCriticalSection(&m_csName);
        strFileName = colName.front();
        colName.erase(colName.begin());
        LeaveCriticalSection(&m_csName);