how can i use the CreateTimerQueueTimer()?

Started by
21 comments, last by cambalinho 7 years, 12 months ago

i'm doing a Timer class for build timers:

1 - normal timer will use the SetTimer()-KillTimer()(yah you don't see it, but i will add it);

2 - for Multimedia Timers(10ms or even 1ms), will use CreateTimerQueueTimer();

- some animated gif's can have a diferent interval between frames, so i must recreate the timer, every cycle;

seen the problem:

1 - i have 1 timer, on my Console Window(like the normal Console), for call the create function, after 1 second:

- the function can be called more than once... isn't correct. here i use a class multithread(for read and write);

2 - after some cycles, i get a crash(thanks for correct me the term).

so what you can tell me more?

i know the CreateTimerQueueTimer() make the program crash, maybe because i use the wrong resolution(the interval is too faster).

Advertisement
I am extremely skeptical that CreateTimerQueueTimer is crashing your program.

Follow these directions to diagnose your crash.

As for the timer itself, I cannot stress enough that you should read the documentation (here). You're using the interval and due-time parameters in a way that does not indicate that you understand how they work.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

only these function give me several problems.

and the macro is wrong:

#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit) \
((Flags)|=(Limit)<<16)

because don't return the result... so i did:

The macro is not wrong. Macros are not functions, they don't need to "return" their results. They are textually-substituted into your source code. Use the macro, don't write your own function to replicate the macro because all you're doing is creating a future bug for yourself when the macro changes but your function didn't.

ok... see these line:


CreateTimerQueueTimer(&m_timerHandle,hTimerQueue,TimerProc,reinterpret_cast<LPVOID>(this),0,(DWORD)intInterval ,WT_SET_MAX_THREADPOOL_THREADS(0,500))

error message:

"lvalue required as left operand of assignment"

how can i avoid these error?

(maybe it's my compiler Code::Blocks - GNU)

I am extremely skeptical that CreateTimerQueueTimer is crashing your program.

Follow these directions to diagnose your crash.

As for the timer itself, I cannot stress enough that you should read the documentation (here). You're using the interval and due-time parameters in a way that does not indicate that you understand how they work.

thanks for sharing that.

please try see the link on 1st - Understand what the crash really means.

thanks for all

"As for the timer itself, I cannot stress enough that you should read the documentation (here). You're using the interval and due-time parameters in a way that does not indicate that you understand how they work."

yes you have right.. i'm confused 100% about:


BOOL WINAPI CreateTimerQueueTimer(
  _Out_    PHANDLE             phNewTimer,
  _In_opt_ HANDLE              TimerQueue,
  _In_     WAITORTIMERCALLBACK Callback,
  _In_opt_ PVOID               Parameter,
  _In_     DWORD               DueTime,
  _In_     DWORD               Period,
  _In_     ULONG               Flags
);

DueTime and Period and, too, the flags.

i understand that my english isn't the best, but i'm confused on who what do :(

can anyone explain better to me, please?


CreateTimerQueueTimer(&m_timerHandle,hTimerQueue,TimerProc,reinterpret_cast<LPVOID>(this),(DWORD)intInterval,0 ,CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(0,500))

- i mistake the interval is the DueTime;

- Period: if the number is zero, it's only fires once. if is more than zero, i will get a crash... so what is the best value?

Exactly as it says in the documentation: Due Time is how long until the timer first fires. Period is how long AFTER THAT it will fire again, and then again, and then again... unless it is zero. If you are getting a crash when you use a nonzero period, it sounds like something about your handler is crashing on the second or some subsequent timer firing.

If you expect the timer to fire once, and then never again, give a Period of zero. If you need it to fire multiple times over time, give it a period and debug your callback for what's really going on.

Also, on a resource waste note... you are creating a TimerQueue (a somewhat heavyweight object) for each of your timers, and then creating only one TimerQueueTimer (a lightweight object) in each of them.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

thanks for all.


CreateTimerQueueTimer(&m_timerHandle,hTimerQueue,Timer::TimerProc,reinterpret_cast<LPVOID>(this),(DWORD)intInterval,(DWORD)intInterval ,CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(0,500));

now i understand why the parameters must be the same.

now i'm trying fix 1 problem.

i will be back.

thanks for all

now works fine:


ULONG CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(ULONG Flags=0, ULONG Limit=500)
{
    return ((Flags)|=(Limit)<<16);
}

class Timer
{

private:
    static unsigned int TimerCount;
    HANDLE m_timerHandle=NULL;
    UINT_PTR timerid;
    UINT m_uResolution=0;
    unsigned int TimerID=0;
    unsigned int intInterval=0;
    HANDLE hTimerQueue=NULL;
    HANDLE gDoneEvent= CreateEvent(NULL, TRUE, FALSE, NULL);

    static void CALLBACK TimerProc(PVOID InstancePointer, BOOLEAN TimerOrWaitFired)
    {
        Timer* obj=reinterpret_cast<Timer*>(InstancePointer);
        if(obj->timerprocedure)
        {
            obj->timerprocedure();
            SetEvent(obj->gDoneEvent);
        }
    }

public:

    std::function<void()> timerprocedure=EmptyEvent;
    Timer(std::function<void()> tmrprocedure=EmptyEvent)
    {
        TimerCount++;
        TimerID=TimerCount-1;
        timerprocedure=tmrprocedure;
    }

    void Stop()
    {
        WaitForSingleObject(&gDoneEvent,INFINITE);
        DeleteTimerQueueTimer(hTimerQueue, m_timerHandle, NULL);
        CloseHandle (m_timerHandle);
        DeleteTimerQueue(hTimerQueue);
        m_timerHandle=NULL;
    }

    unsigned int GetInterval()
    {
        return intInterval;
    }

    void SetInterval(unsigned int uintInterval)
    {
        intInterval = uintInterval;
    }

    property <unsigned int> Interval{GetProperty(Timer::GetInterval),SetProperty(Timer::SetInterval)};

    void Start(bool blnPeriodic=true)
    {
        if(m_timerHandle!=NULL)
            Stop();
        ULONG flags;
        DWORD dwPeridic;
        if(blnPeriodic==true)
        {
            flags=CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(WT_EXECUTEDEFAULT,500);
            dwPeridic=(DWORD)intInterval;
        }
        else
        {
            flags=CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS(WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE,500);
            dwPeridic=0;
        }
        hTimerQueue = CreateTimerQueue();
        if (CreateTimerQueueTimer(&m_timerHandle,hTimerQueue,Timer::TimerProc,reinterpret_cast<LPVOID>(this),(DWORD)intInterval,dwPeridic ,flags)==FALSE)
            DebugText("error\t" + to_string(GetLastError()));
    }

    ~Timer()
    {
        if(m_timerHandle!=NULL)
            Stop();
        TimerCount=TimerCount-1;

    }
};
unsigned int Timer::TimerCount=0;

now it's prepared for once.

please i need 2 corrections:

1 - everytime that i use a Multithread's or a Timer's, i must use Wait functions with CreateEvent() and SetEvent()?

2 - i don't have sure, but seems that i can control the number of timers, but for more than 10ms, it's the best use the SetTimer() and KillTimer(), or i use the CreateTimerQueueTimer() for both?

i must use the CreateTimerQueueTimerWT_SET_MAX_THREADPOOL_THREADS() or i will get errors on lValue, like i said before.

thanks for all to all

thank you

This topic is closed to new replies.

Advertisement