/// <summary>
        ///     Worker thread procedure which implements the main animation loop.
        ///     NOTE: This is the ONLY code the worker thread executes, keeping it in one method helps better understand
        ///     any synchronization issues.
        ///     WARNING: Also, this is the only place where ImageInfo objects (not the contained image object) are modified,
        ///     so no access synchronization is required to modify them.
        /// </summary>
        private static void AnimateImages()
        {
            Debug.Assert(s_imageInfoList != null, "Null images list");
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            while (true)
            {
                Thread.Sleep(40);

                // Because Thread.Sleep is not accurate, capture how much time has actually elapsed during the animation
                long timeElapsed = stopwatch.ElapsedMilliseconds;
                stopwatch.Restart();

                // Acquire reader-lock to access imageInfoList, elements in the list can be modified w/o needing a writer-lock.
                // Observe that we don't need to check if the thread is waiting or a writer lock here since the thread this
                // method runs in never acquires a writer lock.
                s_rwImgListLock.AcquireReaderLock(Timeout.Infinite);
                try
                {
                    for (int i = 0; i < s_imageInfoList.Count; i++)
                    {
                        ImageInfo imageInfo = s_imageInfoList[i];

                        if (imageInfo.Animated)
                        {
                            imageInfo.AdvanceAnimationBy(timeElapsed);

                            if (imageInfo.FrameDirty)
                            {
                                s_anyFrameDirty = true;
                            }
                        }
                    }
                }
                finally
                {
                    s_rwImgListLock.ReleaseReaderLock();
                }
            }
        }