Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
Developer Community or GitHub with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
We're seeing problems with Timers that affect a handful of Android devices.
We have a simple timer that loops at an interval of 200ms and should print
to the console.
On a particular device (Moto X, Android 4.4), the timer sometimes fails to
fire at all. I can best reproduce this when our app is freshly booted, in
which case it repros every time. Otherwise it takes me 10-20 runs or more
I have tried using both System.Timers.Timer and System.Threading.Timer and
both show the same bug.
We have not gotten a repro on other devices-- the Nexus 5 (Android 4.4) and
Asus K00G (Android 4.2.2).
Our device is very active during a fresh boot, setting up various services.
I suspect it is either related to garbage collection or a thread pool
issue. However I maintain a strong reference to the timer in my Activity to
try and avoid GC-related problems.
Attached are the various snippets for the timer. In the error case, we see
this log, no matter how much time passes (eg, no "TICK / TOCK").
STARTED RECORDING ON
Created attachment 5676 [details]
Code snippet from desk case
System.Timers.Timer is implemented using System.Threading.Timer, so it is effectively the same code with just one more level of indirection if using the former. The latter is running a loop in a threadpool thread and iterates over the list of registered callbacks/timers waiting between runs for the smallest amount of time to schedule the next due timer. It is, therefore, NOT a reliable source of timed events as every thread can be blocked for any amount of time, especially on devices where there's just a single CPU core or the cores are disabled by default and especially during heavy CPU activity. In order to be able to see what's going on we'd have to be able to reproduce this issue reliably, check the number of threads running, their state (both managed and unmanaged).
Both timer classes are very simple and for very basic uses. If you require a more reliable timer source I'd recommend using the operating system's setitimer/getitimer APIs directly as they are designed for reliable delivery of timeout events to the application. Each process on Unix systems has 3 different timers available through those APIs:
* real time
This one will deliver the SIGALRM signal when it expires and it decrements in real time.
This one will deliver the SIGVTALRM signal when it expires and it decrements only when the process is actually executing (that is outside system calls).
The least useful for you, this one delivers SGPROF and is decrementing both in kernel and user space.
You can also implement your own simple timer in the fashion similar to System.Threading.Timer but using a dedicated thread instead of a threadpool one. Note however that it will still be dependent on the number of CPU cores in the device and will NOT guarantee execution in a timely manner.