Reputation: 3003
I faced with some strange Grand Central Dispatch timer behavior. It breaks its period of firing and freezes for many seconds. While I need to ping my server to stay "online", this behavior is strongly unsuitable.
Here the timer creation code.
// pingTimer and pingQueue are class members
- (void)createPingTimerSource
{
// check timer exists
if(pingTimer)
{
// suspend source and cancel
[self setPingTimerSuspended:YES];
dispatch_source_cancel(pingTimer);
}
// check having queue, create if doesn't exist
if(!pingQueue)
pingQueue = dispatch_queue_create(kDispatchTimerQueueLabel, NULL);
// create timer dispatch source
pingTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, pingQueue);
dispatch_source_set_timer(pingTimer, dispatch_time(DISPATCH_TIME_NOW, 5*NSEC_PER_MSEC), 5*NSEC_PER_MSEC, NSEC_PER_SEC/10);
// set event handler
dispatch_source_set_event_handler(pingTimer,^{
printf("[%llu] gcd timer fired.\n", mach_absolute_time()/NSEC_PER_SEC);
dispatch_async(dispatch_get_main_queue(), ^{
[self sendPingToServer];
});
});
// set cancel handler
dispatch_source_set_cancel_handler(pingTimer, ^{
// release dispatch source if exists
if(pingTimer)
dispatch_release(pingTimer);
// check timer queue exists and release if does
if(pingQueue)
dispatch_release(pingQueue);
});
}
Here the log console shot.
Thank you for help.
Upvotes: 0
Views: 377
Reputation: 438232
A couple of possibilities:
Your pingQueue
might be blocked doing something, and as a serial queue, it won't be able to perform new dispatched blocks until the prior dispatched block finishes and the queue once again available.
You might try logging the starting and stopping of your ping routine, and make sure that the problem is really the failure of the timer to fire and not that the queue is blocked and therefore cannot honor new timer requests.
If your app is not in foreground, the "App Nap" feature may try to coalesce timers to minimize power drain. Thus the timers may not be called with the frequency that you expected.
You can tell your timer to not participate by supplying DISPATCH_TIMER_STRICT
as the third parameter to dispatch_source_create
, though this is obviously discouraged unless absolutely needed (e.g. interfacing with hardware that cannot tolerate timer deviation), as you lose the power savings App Nap provides.
See WWDC 2013 video Improving Power Efficiency with App Nap.
Upvotes: 1
Reputation: 8954
dispatch_queue_create
doesn't guarantee you that it creates independent thread for processing blocks.
Here is a quote from Apple documentation
Queues are not bound to any specific thread of execution
and blocks submitted to independent queues may execute concurrently.
So this means if you have many queues that are under pressure, can cause your pingQueue to stop responding and executing blocks with delay.
Upvotes: 1