调用SetEvent(m_hShutdownEvent)设置事件对象的状态后,调用WaitForSingleObject.返回结果不确定的问题.
//先给出主要的代码.请您重点看标红的部分.
/* CScanPath.h */
#include <windows.h>
class CScanPath
{
public:
HRESULT StopScan();
typedef void ( *pCallBackFunction ) ( LPVOID);
HRESULT RunScan( char * path, LPVOID Fonction );
private:
static UINT WINAPI RunScanThread( LPVOID pParam );
HRESULT ScanPath( char * rep, int mode );
pCallBackFunction m_ScanPathCallBack;
HANDLE m_hThread;
HANDLE m_hShutdownEvent; // Shutdown Event handle (causes thread to exit)
HRESULT ShutdownThread( )
{
HRESULT hr = S_OK;
if( NULL != m_hThread )
{
::SetEvent(m_hShutdownEvent);
if ( WAIT_TIMEOUT == WaitForSingleObject( m_hThread, 1000 ) )
{
::TerminateThread( m_hThread, -1000 );
hr = S_FALSE;
}
::CloseHandle( m_hThread );
m_hThread = NULL;
}
::ResetEvent( m_hShutdownEvent );
return hr;
}
public :
HANDLE& GetShutdownEvent( )
{
return CScanPath::m_hShutdownEvent;
}
int mode;
char path[MAX_PATH];
char path2[MAX_PATH];
};
/* CScanPath.cpp */
#include "StdAfx.h"
#include "ScanPath.h"
CScanPath::CScanPath()
:m_dwFilesCount(0)
,m_dwFilesSizes(0)
,m_ScanPathCallBack(NULL)
,m_hThread(NULL)
, m_hShutdownEvent( ::CreateEvent( NULL, TRUE, FALSE, NULL ) )
{
}
CScanPath::~CScanPath()
{
ShutdownThread( );
::CloseHandle( m_hShutdownEvent );
}
HRESULT CScanPath::ScanPath( char *rep, int mode )
{
WIN32_FIND_DATA FindFileData;
char path[MAX_PATH];
HANDLE hFind;
DWORD a = 0;
if( WAIT_OBJECT_0 == WaitForSingleObject( this ->GetShutdownEvent( ), 0 ) )
{ AfxMessageBox("GetShutdownEvent can't take effect. Here cann't get the current state of m_hShutdownEvent event variable,program cann't run to here.");
return 1;
}
AfxMessageBox("Program can run to here.This is not what I want.");
}
DWORD CScanPath::GetDirFilesNumbers(char *path)
{
m_dwFilesCount = 0;
ScanPath( path, CScanPath::MODE_COUNT );
return m_dwFilesCount;
}
HRESULT CScanPath::RunScan( char * path, LPVOID Fonction )
{
HRESULT hr = S_OK;
::ResetEvent( m_hShutdownEvent );
::SetEvent(CScanPath::m_hShutdownEvent);//m_hShutdownEvent currenty in singal state if( WAIT_OBJECT_0 == WaitForSingleObject( GetShutdownEvent( ), 0 )//唯一得到事件变量为有信号的语句 )
{
AfxMessageBox("Here can get the current state of m_hShutdownEvent variable."); //return 1;
}
m_ScanPathCallBack = (pCallBackFunction)Fonction;
strncpy( CScanPath::path, path, MAX_PATH - 1);
mode = CScanPath::MODE_FUNC;
if( SUCCEEDED( hr = ShutdownThread( ) ) )
{
if( NULL == ( m_hThread = (HANDLE)_beginthreadex(
NULL,
0,
RunScanThread,
static_cast<LPVOID>( this ),//point this pointer 0,
NULL)) )
{
return 1;
}
return hr;
}
return hr;
}
HRESULT CScanPath::StopScan()
{
return ShutdownThread( );
}
UINT CScanPath::RunScanThread( LPVOID pParam )
{
CScanPath* pCScanPath = reinterpret_cast< CScanPath* >( pParam );//change the type of pointer
if( WAIT_OBJECT_0 == WaitForSingleObject( pCScanPath->GetShutdownEvent( ), 0 ) )
{
AfxMessageBox("Here cann't get the current state of m_hShutdownEvent event variable,program cann't run to here."); return 2;
}
pCScanPath->ScanPath( pCScanPath->path, pCScanPath->mode );
return 0;
}
//CScanPathDemoDlg.h
class CScanPathDemoDlg : public CDialog
{
public:
CScanPath Scan;
CImageList m_Image;
static HRESULT ScanFunction( LPVOID pParam);
CButton m_BoutonBrowse;
CString m_strDir;
public:
};
// ScanPathDemoDlg.cpp : implementation file
#include "stdafx.h"
#include "ScanPathDemo.h"
#include "ScanPathDemoDlg.h"
#include "FolderDialog.h"
#include ".\scanpathdemodlg.h"
CScanPathDemoDlg * _this;
protected:
DECLARE_MESSAGE_MAP()
};
// CScanPathDemoDlg dialog
CScanPathDemoDlg::CScanPathDemoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CScanPathDemoDlg::IDD, pParent)
{
m_strDir = _T("");
}
void CScanPathDemoDlg::DoDataExchange(CDataExchange* pDX)
{
}
BEGIN_MESSAGE_MAP(CScanPathDemoDlg, CDialog)
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)
END_MESSAGE_MAP()
// CScanPathDemoDlg message handlers
BOOL CScanPathDemoDlg::OnInitDialog()
{
char WindowsDir[MAX_PATH];
GetWindowsDirectory( WindowsDir, MAX_PATH );
m_strDir = WindowsDir;
}
HIMAGELIST CScanPathDemoDlg::GetSysImageList()
{
himl = (HIMAGELIST)SHGetFileInfo(
_T("C:\\"), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
return himl;
}
int CScanPathDemoDlg::GetSysIlIndex(LPCTSTR szFileName)
{
SHFILEINFO sfi;
::SHGetFileInfo(
szFileName, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
return sfi.iIcon;
}
void CScanPathDemoDlg::OnOK()
{
UpdateData( TRUE );
CString Text;
m_BoutonStart.GetWindowText( Text );
if( Text == "START" )
{
if( m_strDir.IsEmpty() || !SetCurrentDirectory( m_strDir ) )
{
return;
}
m_BoutonStart.SetWindowText("STOP");
m_list.DeleteAllItems();
m_StaticEvent.SetWindowText("Get number of files, please wait...");
dwNumFiles = Scan.GetDirFilesNumbers( m_strDir.GetBuffer(0) );
m_progress.SetRange32(0, dwNumFiles );
m_progress.SetStep(1);
m_progress.SetPos(0);
_this = this;
Scan.RunScan( m_strDir.GetBuffer(0), ScanFunction );
}
else
{
Scan.StopScan();
m_BoutonStart.SetWindowText("START");
}
}
HRESULT CScanPathDemoDlg::ScanFunction( LPVOID pParam)
{
CScanPath* pCScanPath2=reinterpret_cast<CScanPath*>(pParam);
CString text;
if( WAIT_OBJECT_0 == WaitForSingleObject( pCScanPath2->GetShutdownEvent( ), 0 ) )//The result is false {AfxMessageBox("SF");
return 3;
}
else
{
_this->m_progress.StepIt();
_this->m_list.InsertItem( 0, pCScanPath2->path2, _this->GetSysIlIndex( pCScanPath2->path2 ) );
if(( _this->m_progress.GetPos() >= (int)_this->dwNumFiles )&&(WAIT_OBJECT_0 != WaitForSingleObject( pCScanPath2->GetShutdownEvent( ), 0 )))
{
_this->m_BoutonStart.SetWindowText("START");
}
else
return 4;
}
}
void CScanPathDemoDlg::OnBrowse()
{
CFolderDialog Folder;
if( IDOK == Folder.DoModal() )
{
m_strDir = Folder.GetPathName();
UpdateData( FALSE );
}
}
void CScanPathDemoDlg::OnBnClickedCancel()
{
Scan.StopScan( );
OnCancel();
}
//此为一对话框程序.当点开始时启动一个辅助线程.由于我连续使用了::ResetEvent( m_hShutdownEvent );
::SetEvent(m_hShutdownEvent);事件变量m_hShutdownEvent应处于有信号状态.程序在调用_beginthreadex启动
线程后,调用WaitForSingleObject本应返回WAIT_OBJECT_0(我的想法,这可能正式我错的地方.)但是结果不等.程序进入循环.而且接下来的WaitForSingleObject的结果都不等于WAIT_OBJECT_0.(只有唯一一个WaitForSingleObject语句返回的是有信号状态)我不能理解.我在静态成员函数访问非静态成员函数时使用的是传递this指针的方式.(我的开发环境是Visual C++ .net 2003和windows 2000 Server,完整代码已附上.)我已查找了许多地方的资料.如google.《C++ 编程艺术》《VC.net技术内幕》都未找到详细说明.请有经验的朋友或老师给我一些指点,给我一个努力的方向也好.不胜感激!