Есть такой код (мой).
Смотрю что будет , если использовать
1. Сбрасываемое вручную событие
2. Сбрасываемое автоматически
#include "stdafx.h"
using std::wcout;
using std::endl;
using std::hex;
using std::dec;
#ifndef BEGIN_NAMESPACE
#define BEGIN_NAMESPACE(x)
#define END_NAMESPACE(x)
#endif
BEGIN_NAMESPACE(REGISTEROBJECT)
VOID WINAPI RegCallBack(PVOID pvContext,BOOLEAN)
{
Sleep(1000);
VOID* pointer = pvContext;
wcout << GetCurrentThreadId() << L" " << (DWORD)pvContext <<L"\n";
}
int _tmain(int argc, _TCHAR* argv[])
{
const DWORD SOME_NUM = 10;
HANDLE hEventAr[SOME_NUM];
HANDLE hReg[SOME_NUM];
BOOL bAutoReset = TRUE;//FALSE;
for(DWORD i=0;i<SOME_NUM;++i)
{
hEventAr[i] = CreateEvent(0,!bAutoReset,FALSE,0);
wcout << L"bOK = " << ::RegisterWaitForSingleObject(&hReg[i],hEventAr[i],&RegCallBack,(PVOID)i,-1,WT_EXECUTEINWAITTHREAD) << L"\n";
}
SetEvent(hEventAr[0]);
wcout << L"RetWait : " << UnregisterWaitEx(hReg[0],(HANDLE)(-1)) << L" Error : " << GetLastError() << L"\n";
/*
Unregister...
CloseHandle..
*/
return 0;
}
END_NAMESPACE
в 1 (вручную) случае "цикл"
в 2 (авто) случае после первого сброса выполнение кэллбэка только один раз
Как-то флаги на это влияют?(Register...)
Почему?(не понимаю почему во втором случае сразу возвращает управление Unreg...)
п.с. ругается на приведение PVOID<->DWORD У меня из размеры равны оба 4 байтам.В чем проблема?
warning C4311: 'type cast' : pointer truncation from 'PVOID' to 'DWORD'
warning C4312: 'type cast' : conversion from 'DWORD' to 'PVOID' of greater size
Спасибо.
Здравствуйте, WinUser, Вы писали:
WU>Есть такой код (мой).
WU>Смотрю что будет , если использовать
WU>1. Сбрасываемое вручную событие
WU>2. Сбрасываемое автоматически
WU>WU>#include "stdafx.h"
WU>using std::wcout;
WU>using std::endl;
WU>using std::hex;
WU>using std::dec;
WU>#ifndef BEGIN_NAMESPACE
WU> #define BEGIN_NAMESPACE(x)
WU> #define END_NAMESPACE(x)
WU>#endif
WU>BEGIN_NAMESPACE(REGISTEROBJECT)
WU> VOID WINAPI RegCallBack(PVOID pvContext,BOOLEAN)
WU> {
WU> Sleep(1000);
WU> VOID* pointer = pvContext;
WU> wcout << GetCurrentThreadId() << L" " << (DWORD)pvContext <<L"\n";
WU> }
WU> int _tmain(int argc, _TCHAR* argv[])
WU> {
WU> const DWORD SOME_NUM = 10;
WU> HANDLE hEventAr[SOME_NUM];
WU> HANDLE hReg[SOME_NUM];
WU> BOOL bAutoReset = TRUE;//FALSE;
WU> for(DWORD i=0;i<SOME_NUM;++i)
WU> {
WU> hEventAr[i] = CreateEvent(0,!bAutoReset,FALSE,0);
WU> wcout << L"bOK = " << ::RegisterWaitForSingleObject(&hReg[i],hEventAr[i],&RegCallBack,(PVOID)i,-1,WT_EXECUTEINWAITTHREAD) << L"\n";
WU> }
WU> SetEvent(hEventAr[0]);
WU> wcout << L"RetWait : " << UnregisterWaitEx(hReg[0],(HANDLE)(-1)) << L" Error : " << GetLastError() << L"\n";
WU> /*
WU> Unregister...
WU> CloseHandle..
WU> */
WU> return 0;
WU> }
WU>END_NAMESPACE
WU>
WU>в 1 (вручную) случае "цикл"
WU>в 2 (авто) случае после первого сброса выполнение кэллбэка только один раз
Здесь должно быть наоботот, правда?! Перепутали?
WU>Как-то флаги на это влияют?(Register...)
Да, для manual reset event не следует вызывать PulseEvent, если не указаны флаги WT_EXECUTEINWAITTHREAD или WT_EXECUTEONLYONCE, так как в этом случае ожидающий поток не сможет обработать событие перехода объекта в сигнальное состояние.
WU>Почему?(не понимаю почему во втором случае сразу возвращает управление Unreg...)
Что значит сразу "возвращает управление"? Почему передаете не валидный хэндл? Второй параметер — это хендл объекта, устанавливаемого в сигнальное состояние после удаления. — UnregisterWaitEx(hReg[0],/*здесь*/(HANDLE)(-1));
WU>п.с. ругается на приведение PVOID<->DWORD У меня из размеры равны оба 4 байтам.В чем проблема?
WU>warning C4311: 'type cast' : pointer truncation from 'PVOID' to 'DWORD'
WU>warning C4312: 'type cast' : conversion from 'DWORD' to 'PVOID' of greater size
Компилятор не ругается, а предупреждает Вас, что бы обратили внимание на эти строки, еще раз проверили, и если все нормально, сделали приведение типов явно, тем самым указывая ему, что Вы точно уверены в том что делаете.
WU>>в 1 (вручную) случае "цикл"
WU>>в 2 (авто) случае после первого сброса выполнение кэллбэка только один раз
M>Здесь должно быть наоботот, правда?! Перепутали?
WU>>Как-то флаги на это влияют?(Register...)
M>Да, для manual reset event не следует вызывать PulseEvent, если не указаны флаги WT_EXECUTEINWAITTHREAD или WT_EXECUTEONLYONCE, так как в этом случае ожидающий поток не сможет обработать событие перехода объекта в сигнальное состояние.
WU>>Почему?(не понимаю почему во втором случае сразу возвращает управление Unreg...)
M>Что значит сразу "возвращает управление"? Почему передаете не валидный хэндл? Второй параметер — это хендл объекта, устанавливаемого в сигнальное состояние после удаления. — UnregisterWaitEx(hReg[0],/*здесь*/(HANDLE)(-1));
WU>>п.с. ругается на приведение PVOID<->DWORD У меня из размеры равны оба 4 байтам.В чем проблема?
WU>>warning C4311: 'type cast' : pointer truncation from 'PVOID' to 'DWORD'
WU>>warning C4312: 'type cast' : conversion from 'DWORD' to 'PVOID' of greater size
M>Компилятор не ругается, а предупреждает Вас, что бы обратили внимание на эти строки, еще раз проверили, и если все нормально, сделали приведение типов явно, тем самым указывая ему, что Вы точно уверены в том что делаете.
bAutoReset = TRUE Возращается управление после выполнения RegCallBack Это не понятно Почему он дальше не ждет следующего срабатывания от hEventAr[0];
bAutoReset = FALSE Не возращает управление (что вполне логично) Постоянно выполняется RegCallBack
http://msdn.microsoft.com/en-us/library/ms686876(VS.85).aspx
If this parameter is INVALID_HANDLE_VALUE, the function waits for all callback functions to complete before returning.
Я передаю -1 или INVALID_HANDLE_VALUE Специально для того,чтобы дождаться выполнения всех функций.
п.спод циклом я НЕ имел в виду for(DWORD i=0;i<SOME_NUM;++i) Выставил SOME_NUM=1; чтобы не путаться.
Хм.После выставления SOME_NUM = 1 сразу возвращается управление,лучше ставить хотя бы 2