调用SetEvent(m_hShutdownEvent)设置事件对象的状态后,调用WaitForSingleObject.返回结果不确定的问题.

BlueSky0246 2008-05-15 12:58:37
//先给出主要的代码.请您重点看标红的部分.
/* 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技术内幕》都未找到详细说明.请有经验的朋友或老师给我一些指点,给我一个努力的方向也好.不胜感激!
...全文
518 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
BlueSky0246 2008-05-26
  • 打赏
  • 举报
回复
我在www.codeguru.com的simple thread文章中找到了相关的答案.问题大概出在消息的处理上.不过还是非常感谢大家的热心帮助.
Y神圣 2008-05-17
  • 打赏
  • 举报
回复
在对Event作用的时候用Critical Section包起来看看(包括SetEvent(),RsetEvent())。
liyinlei 2008-05-17
  • 打赏
  • 举报
回复
分析一下楼主代码
进入Scan.RunScan( m_strDir.GetBuffer(0), ScanFunction );
在RunScan中设置事件为“有信号”状态
然后启动一个线程
在新的线程里运行 RunScanThread 函数
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; //因为事件为有信号,应该进入这里,执行 return 2.到此线程函数就执行完毕了,该线程也就结束了,
//不是很清楚楼主描述的问题。


}
zwh37333 2008-05-16
  • 打赏
  • 举报
回复
事件这个东西在Waitfor的时候,有副作用,请参看Windows核心编程。
buyong 2008-05-16
  • 打赏
  • 举报
回复
代码太长了,没仔细看
不过MFC中应使用AfxBeginThread代替_beginthreadex
kikistorm 2008-05-16
  • 打赏
  • 举报
回复
WaitForSingleObject后ResetEvent
BlueSky0246 2008-05-15
  • 打赏
  • 举报
回复
原代码多次上传不成功,明天再上传.

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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