几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量  


返回   几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 » 仿射空间:CAX软件开发(三)二次开发与程序设计 » 程序设计 » vc编程
用户名
密码
注册 帮助 会员 日历 银行 搜索 今日新帖 标记论坛为已读


回复
 
主题工具 搜索本主题 显示模式
旧 2010-04-24, 10:32 PM   #1
huangyhg
超级版主
 
huangyhg的头像
 
注册日期: 04-03
帖子: 18592
精华: 36
现金: 249466 标准币
资产: 1080358888 标准币
huangyhg 向着好的方向发展
默认 How To Use a Waitable Timer with an Asynchronous Procedure Call

When using waitable timers, you need to define the constant _WIN32_WINNT as 0x0400. This constant should be defined before the inclusion of <windows.h> to ensure that the proper waitable timer function prototypes are declared.

You create a waitable timer by calling CreateWaitableTimer(). This function returns a handle to the kernel object. If the timer already exists, you can obtain a process-relative handle by using OpenWaitableTimer(). The handle, whether obtained through CreateWaitableTimer() or OpenWaitableTimer(), must be released when the timer is no longer needed. Do this by calling CloseHandle().

The timer is set with a call to SetWaitableTimer(). The timer can be set for a specific time (for example, December 16, 1999 at 9:45 PM) or a relative time (for example, 5 minutes from now). SetWaitableTimer() requires a LARGE_INTEGER for the due time. This value should be in the format described by the FILETIME structure. If the value is positive, it represents a specific time. If it is negative, it represents a relative time in 100-nanosecond units. The sample code shown later uses a relative time. The timer will become signaled 5 seconds after the call to SetWaitableTimer().

You can also set the timer to periodically re-signal itself. Do this by passing a periodic value (in milliseconds) as the third parameter to SetWaitableTimer(). If a periodic timer is required, you should create the timer as an auto-reset timer by passing FALSE as the second parameter to CreateWaitableTimer(). This sample sets a timer with a period of 2 seconds.

You can associate an asynchronous procedure call (APC) function with a waitable timer when the timer is set. The APC function is called a completion routine. The address of the completion routine is the fourth parameter to SetWaitableTimer(). The fifth parameter is a void pointer that you can use to pass arguments to the completion routine.

As with all APCs, a thread must be in an alertable state to execute the completion routine. The completion routine will always be executed by the same thread that called SetWaitableTimer(). Thus, this thread must eventually put itself in an alertable state. It accomplishes this by calling one of the following alertable functions: SleepEx()
WaitForSingleObjectEx()
WaitForMultipleObjectsEx()
MsgWaitForMultipleObjectsEx()
SignalObjectAndWait()

Each thread has an APC queue. If there is an entry in the thread's APC queue at the time that one of the above functions is called, the thread is not put to sleep. Instead, the entry is removed from the APC queue and the completion routine is called.

If no entry exists in the APC queue, the thread is suspended until the wait is satisfied. The wait can be satisfied by adding an entry to the APC queue, by a timeout, by a handle becoming signaled, or, in the case of MsgWaitForMultipleObjectsEx(), by adding a message to one of the thread's message queues. If the wait is satisfied by an entry in the APC queue, the thread is awakened and the completion routine is called. In this case, the return value of the function is WAIT_IO_COMPLETION.

IMPORTANT NOTE: After the completion routine is executed, the system checks for another entry in the APC queue to process. An alertable function will return only after all APC entries have been processed. It is, therefore, possible that a call to one of these functions will never return if entries are being added to the APC queue faster than they can be processed. This is especially possible with waitable timers, where the period is shorter than the amount of time required to execute the completion routine.

When you are using a waitable timer with an APC, the thread that sets the timer SHOULD NOT wait on the handle of the timer. By doing this, you cause the thread to wake up as a result of the timer becoming signaled rather than as the result of an entry being added to the APC queue. As a result, the thread is no longer in an alertable state and the completion routine is not called. In the following sample, SleepEx() is used to put the thread in an alertable state. SleepEx() awakens the thread when an entry is added to the thread's APC queue after the timer becomes signaled. [img]/library/images/support/kbgraphics/public/en-us/uparrow.gif[/img]Back to the top
Sample Code

loadTOCNode(2, 'moreinformation'); #define _WIN32_WINNT 0x0400
#include <windows.h>
#include <stdio.h>

#define _SECOND 10000000

typedef struct _MYDATA {
TCHAR *szText;
DWORD dwValue;
} MYDATA;


VOID CALLBACK TimerAPCProc(
LPVOID lpArg, // Data value.
DWORD dwTimerLowValue, // Timer low value.
DWORD dwTimerHighValue ) { // Timer high value.

MYDATA *pMyData = (MYDATA *)lpArg;

printf( "Message: %s\nValue: %d\n\n", pMyData->szText,
pMyData->dwValue );
MessageBeep(0);

}


void main( void ) {

HANDLE hTimer;
BOOL bSuccess;
__int64 qwDueTime;
LARGE_INTEGER liDueTime;
MYDATA MyData;
TCHAR szError[255];

MyData.szText = "This is my data.";
MyData.dwValue = 100;

if ( hTimer = CreateWaitableTimer(
NULL, // Default security attributes.
FALSE, // Create auto-reset timer.
"MyTimer" ) ) { // Name of waitable timer.

__try {

// Create a negative 64-bit integer that will be used to
// signal the timer 5 seconds from now.
qwDueTime = -5 * _SECOND;

// Copy the relative time into a LARGE_INTEGER.
liDueTime.LowPart = (DWORD) ( qwDueTime & 0xFFFFFFFF );
liDueTime.HighPart = (LONG) ( qwDueTime >> 32 );


bSuccess = SetWaitableTimer(
hTimer, // Handle to the timer object.
&liDueTime, // When timer will become signaled.
2000, // Periodic timer interval of 2 seconds.
TimerAPCProc, // Completion routine.
&MyData, // Argument to the completion routine.
FALSE ); // Do not restore a suspended system.

if ( bSuccess ) {

for ( ; MyData.dwValue < 1000; MyData.dwValue += 100 ) {

SleepEx(
INFINITE, // Wait forever.
TRUE ); // IMPORTANT!!! The thread must be in an
// alertable state to process the APC.
}

} else {
wsprintf( szError, "SetWaitableTimer() failed with Error %d.",
GetLastError() );
MessageBox( NULL, szError, "Error", MB_ICONEXCLAMATION );
}

} __finally {
CloseHandle( hTimer );
}

} else {
wsprintf( szError, "CreateWaitableTimer() failed with Error %d.",
GetLastError() );
MessageBox( NULL, szError, "Error", MB_ICONEXCLAMATION );
}

}

http://support.microsoft.com/kb/q184796/
__________________
借用达朗贝尔的名言:前进吧,你会得到信心!
[url="http://www.dimcax.com"]几何尺寸与公差标准[/url]
huangyhg离线中   回复时引用此帖
GDT自动化论坛(仅游客可见)
回复


主题工具 搜索本主题
搜索本主题:

高级搜索
显示模式

发帖规则
不可以发表新主题
不可以回复主题
不可以上传附件
不可以编辑您的帖子

vB 代码开启
[IMG]代码开启
HTML代码关闭

相似的主题
主题 主题发起者 论坛 回复 最后发表
hread call ou huangyhg tec-ease(America) 0 2009-09-05 01:19 PM
【转帖】pure virtual function call on view destruction yang686526 DirectDWG 0 2009-05-07 12:00 PM
【转帖】ambiguous call to overload functions in odstring.h yang686526 DirectDWG 0 2009-05-04 03:56 PM
【转帖】hread call ou yang686526 American standards 0 2009-05-04 10:41 AM
【转帖】dll学习(资料收集) huangyhg vc编程 0 2008-05-17 09:24 PM


所有的时间均为北京时间。 现在的时间是 07:54 PM.


于2004年创办,几何尺寸与公差论坛"致力于产品几何量公差标准GD&T | GPS研究/CAD设计/CAM加工/CMM测量"。免责声明:论坛严禁发布色情反动言论及有关违反国家法律法规内容!情节严重者提供其IP,并配合相关部门进行严厉查处,若內容有涉及侵权,请立即联系我们QQ:44671734。注:此论坛须管理员验证方可发帖。
沪ICP备06057009号-2
更多