Ejemplo n.º 1
0
        /// <devdoc>
        ///     Removes an image from the image manager so it is no longer animated.
        /// </devdoc>
        public static void StopAnimate(Image image, EventHandler onFrameChangedHandler)
        {
            // Make sure we have a list of images
            if (image == null || imageInfoList == null)
            {
                return;
            }

            // Acquire a writer lock to modify the image info list - See comments on Animate() about this locking.

            bool       readerLockHeld      = rwImgListLock.IsReaderLockHeld;
            LockCookie lockDowngradeCookie = new LockCookie();

            threadWriterLockWaitCount++;

            try {
                if (readerLockHeld)
                {
                    lockDowngradeCookie = rwImgListLock.UpgradeToWriterLock(Timeout.Infinite);
                }
                else
                {
                    rwImgListLock.AcquireWriterLock(Timeout.Infinite);
                }
            }
            finally {
                threadWriterLockWaitCount--;
                Debug.Assert(threadWriterLockWaitCount >= 0, "threadWriterLockWaitCount less than zero.");
            }

            try {
                // Find the corresponding reference and remove it
                for (int i = 0; i < imageInfoList.Count; i++)
                {
                    ImageInfoExpender imageInfo = imageInfoList[i];

                    if (image == imageInfo.Image)
                    {
                        if ((onFrameChangedHandler == imageInfo.FrameChangedHandler) || (onFrameChangedHandler != null && onFrameChangedHandler.Equals(imageInfo.FrameChangedHandler)))
                        {
                            imageInfoList.Remove(imageInfo);
                        }
                        break;
                    }
                }
            }
            finally {
                if (readerLockHeld)
                {
                    rwImgListLock.DowngradeFromWriterLock(ref lockDowngradeCookie);
                }
                else
                {
                    rwImgListLock.ReleaseWriterLock();
                }
            }
        }
Ejemplo n.º 2
0
        static void AnimateImages50ms()
        {
            Debug.Assert(imageInfoList != null, "Null images list");

            while (Dispose)
            {
                // Acquire reader-lock to access imageInfoList, elemens 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.
                rwImgListLock.AcquireReaderLock(Timeout.Infinite);
                try {
                    for (int i = 0; i < imageInfoList.Count; i++)
                    {
                        ImageInfoExpender imageInfo = imageInfoList[i];

                        imageInfo.FrameTimer += 5;
                        if (imageInfo.FrameTimer >= imageInfo.FrameDelay(imageInfo.Frame))
                        {
                            imageInfo.FrameTimer = 0;

                            if (imageInfo.Frame + 1 < imageInfo.FrameCount)
                            {
                                imageInfo.Frame++;
                            }
                            else
                            {
                                imageInfo.Frame = 0;
                            }

                            if (imageInfo.FrameDirty)
                            {
                                anyFrameDirty = true;
                            }
                        }
                    }
                }
                finally {
                    rwImgListLock.ReleaseReaderLock();
                }

                Thread.Sleep(50);
            }
            animationThread = null;
        }
Ejemplo n.º 3
0
        ///// <devdoc>
        /////     Advances the frame in all images currently being animated. The new frame is drawn the next time the image is rendered.
        ///// </devdoc>
        //public static void UpdateFrames() {
        //    if (!anyFrameDirty || imageInfoList == null) {
        //        return;
        //    }
        //    if (threadWriterLockWaitCount > 0) {
        //        // Cannot acquire reader lock at this time, frames update will be missed.
        //        return;
        //    }

        //    rwImgListLock.AcquireReaderLock(Timeout.Infinite);

        //    try {
        //        foreach (GifImageInfo imageInfo in imageInfoList) {
        //            // See comment in the class header about locking the image ref.
        //            lock (imageInfo.Image) {
        //                imageInfo.UpdateFrame();
        //            }
        //        }
        //        anyFrameDirty = false;
        //    }
        //    finally {
        //        rwImgListLock.ReleaseReaderLock();
        //    }
        //}

        /// <devdoc>
        ///     Adds an image to the image manager.  If the image does not support animation this method does nothing.
        ///     This method creates the image list and spawns the animation thread the first time it is called.
        /// </devdoc>
        public static void Animate(Image image, EventHandler onFrameChangedHandler)
        {
            if (image == null)
            {
                return;
            }
            ImageInfoExpender imageInfo = null;

            // See comment in the class header about locking the image ref.
            lock (image) {
                // could we avoid creating an ImageInfo object if FrameCount == 1 ?
                imageInfo = new ImageInfoExpender(image);
            }

            // If the image is already animating, stop animating it
            StopAnimate(image, onFrameChangedHandler);

            // Acquire a writer lock to modify the image info list.  If the thread has a reader lock we need to upgrade
            // it to a writer lock; acquiring a reader lock in this case would block the thread on itself.
            // If the thread already has a writer lock its ref count will be incremented w/o placing the request in the
            // writer queue.  See ReaderWriterLock.AcquireWriterLock method in the MSDN.

            bool       readerLockHeld      = rwImgListLock.IsReaderLockHeld;
            LockCookie lockDowngradeCookie = new LockCookie();

            threadWriterLockWaitCount++;

            try {
                if (readerLockHeld)
                {
                    lockDowngradeCookie = rwImgListLock.UpgradeToWriterLock(Timeout.Infinite);
                }
                else
                {
                    rwImgListLock.AcquireWriterLock(Timeout.Infinite);
                }
            }
            finally {
                threadWriterLockWaitCount--;
                Debug.Assert(threadWriterLockWaitCount >= 0, "threadWriterLockWaitCount less than zero.");
            }

            try {
                if (imageInfo.Animated)
                {
                    // Construct the image array
                    //
                    if (imageInfoList == null)
                    {
                        imageInfoList = new List <ImageInfoExpender>();
                    }

                    // Add the new image
                    //
                    imageInfo.FrameChangedHandler = onFrameChangedHandler;
                    imageInfoList.Add(imageInfo);

                    // Construct a new timer thread if we haven't already
                    //
                    if (animationThread == null)
                    {
                        animationThread              = new Thread(new ThreadStart(AnimateImages50ms));
                        animationThread.Name         = typeof(ImageAnimator).Name;
                        animationThread.IsBackground = true;
                        animationThread.Start();
                    }
                }
            }
            finally {
                if (readerLockHeld)
                {
                    rwImgListLock.DowngradeFromWriterLock(ref lockDowngradeCookie);
                }
                else
                {
                    rwImgListLock.ReleaseWriterLock();
                }
            }
        }