Esempio n. 1
0
        public void QueueThumbnailUpdate(IThumbnailProvider updateMe, int thumbSideLength, ThumbnailReadyHandler callback)
        {
            if (thumbSideLength < 1)
            {
                throw new ArgumentOutOfRangeException("thumbSideLength", "must be greater than or equal to 1");
            }

            lock (this.updateLock)
            {
                bool doIt = false;
                ThumbnailStackItem addMe = new ThumbnailStackItem(updateMe, callback, thumbSideLength);

                if (this.renderQueue.Count == 0)
                {
                    doIt = true;
                }
                else
                {
                    ThumbnailStackItem top = this.renderQueue.Peek();

                    if (addMe != top)
                    {
                        doIt = true;
                    }
                }

                // Only add this item to the queue if the item is not already at the top of the queue
                if (doIt)
                {
                    this.renderQueue.Push(addMe);
                }

                Monitor.Pulse(this.updateLock);
            }
        }
Esempio n. 2
0
        private void RenderThreadImpl()
        {
            while (true)
            {
                ThumbnailStackItem renderMe = new ThumbnailStackItem();

                // Wait for either a new item to render, or a signal to quit
                lock (this.updateLock)
                {
                    if (this.quitRenderThread)
                    {
                        return;
                    }

                    while (this.renderQueue.Count == 0)
                    {
                        Monitor.Wait(this.updateLock);

                        if (this.quitRenderThread)
                        {
                            return;
                        }
                    }

                    this.renderingInactive.Reset();
                    renderMe = this.renderQueue.Pop();
                }

                // Sleep for a short while. Our main goal is to ensure that the
                // item is not re-queued for updating very soon after we start
                // rendering it.
                Thread.Sleep(this.updateLatency);

                bool doRender = true;

                // While we were asleep, ensure that this same item has not been
                // re-added to the render queue. If it has, we will skip rendering
                // it. This covers the scenario where an item is updated many
                // times in rapid succession, in which case we want to wait until
                // the item has settled down before spending any CPU time rendering
                // its thumbnail.
                lock (this.updateLock)
                {
                    if (this.quitRenderThread)
                    {
                        return;
                    }

                    if (this.renderQueue.Count > 0)
                    {
                        if (renderMe == this.renderQueue.Peek())
                        {
                            doRender = false;
                        }
                    }
                }

                if (doRender)
                {
                    try
                    {
                        Surface thumb;

                        using (new ThreadBackground(ThreadBackgroundFlags.All))
                        {
                            thumb = renderMe.First.RenderThumbnail(renderMe.Third);
                        }

                        // If this same item has already been re-queued for an update, then throw
                        // away what we just rendered. Otherwise we may get flickering as the
                        // item was being updated while we were rendering the preview.
                        bool discard = false;

                        lock (this.updateLock)
                        {
                            if (this.quitRenderThread)
                            {
                                thumb.Dispose();
                                thumb = null;
                                return;
                            }

                            if (this.renderQueue.Count > 0)
                            {
                                if (renderMe == this.renderQueue.Peek())
                                {
                                    discard = true;
                                    thumb.Dispose();
                                    thumb = null;
                                }
                            }
                        }

                        if (!discard)
                        {
                            OnThumbnailReady(renderMe.First, renderMe.Second, thumb);
                        }
                    }

                    catch (Exception ex)
                    {
                        try
                        {
                            Tracing.Ping("Exception in RenderThread while calling CreateThumbnail: " + ex.ToString());
                        }

                        catch (Exception)
                        {
                        }
                    }
                }

                this.renderingInactive.Set();
            }
        }
Esempio n. 3
0
        private void RenderThreadImpl()
        {
            while (true)
            {
                ThumbnailStackItem renderMe = new ThumbnailStackItem();

                // Wait for either a new item to render, or a signal to quit
                lock (this.updateLock)
                {
                    if (this.quitRenderThread)
                    {
                        return;
                    }

                    while (this.renderQueue.Count == 0)
                    {
                        Monitor.Wait(this.updateLock);

                        if (this.quitRenderThread)
                        {
                            return;
                        }
                    }

                    this.renderingInactive.Reset();
                    renderMe = this.renderQueue.Pop();
                }

                // Sleep for a short while. Our main goal is to ensure that the
                // item is not re-queued for updating very soon after we start
                // rendering it.
                Thread.Sleep(this.updateLatency);

                bool doRender = true;

                // While we were asleep, ensure that this same item has not been
                // re-added to the render queue. If it has, we will skip rendering
                // it. This covers the scenario where an item is updated many
                // times in rapid succession, in which case we want to wait until
                // the item has settled down before spending any CPU time rendering
                // its thumbnail.
                lock (this.updateLock)
                {
                    if (this.quitRenderThread)
                    {
                        return;
                    }

                    if (this.renderQueue.Count > 0)
                    {
                        if (renderMe == this.renderQueue.Peek())
                        {
                            doRender = false;
                        }
                    }
                }

                if (doRender)
                {
                    try
                    {
                        Surface thumb;

                        using (new ThreadBackground(ThreadBackgroundFlags.All))
                        {
                            thumb = renderMe.First.RenderThumbnail(renderMe.Third);
                        }

                        // If this same item has already been re-queued for an update, then throw
                        // away what we just rendered. Otherwise we may get flickering as the
                        // item was being updated while we were rendering the preview.
                        bool discard = false;

                        lock (this.updateLock)
                        {
                            if (this.quitRenderThread)
                            {
                                thumb.Dispose();
                                thumb = null;
                                return;
                            }

                            if (this.renderQueue.Count > 0)
                            {
                                if (renderMe == this.renderQueue.Peek())
                                {
                                    discard = true;
                                    thumb.Dispose();
                                    thumb = null;
                                }
                            }
                        }

                        if (!discard)
                        {
                            OnThumbnailReady(renderMe.First, renderMe.Second, thumb);
                        }
                    }

                    catch (Exception ex)
                    {
                        try
                        {
                            Tracing.Ping("Exception in RenderThread while calling CreateThumbnail: " + ex.ToString());
                        }

                        catch (Exception)
                        {
                        }
                    }
                }

                this.renderingInactive.Set();
            }
        }
Esempio n. 4
0
        public void QueueThumbnailUpdate(IThumbnailProvider updateMe, int thumbSideLength, ThumbnailReadyHandler callback)
        {
            if (thumbSideLength < 1)
            {
                throw new ArgumentOutOfRangeException("thumbSideLength", "must be greater than or equal to 1");
            }

            lock (this.updateLock)
            {
                bool doIt = false;
                ThumbnailStackItem addMe = new ThumbnailStackItem(updateMe, callback, thumbSideLength);

                if (this.renderQueue.Count == 0)
                {
                    doIt = true;
                }
                else
                {
                    ThumbnailStackItem top = this.renderQueue.Peek();

                    if (addMe != top)
                    {
                        doIt = true;
                    }
                }

                // Only add this item to the queue if the item is not already at the top of the queue
                if (doIt)
                {
                    this.renderQueue.Push(addMe);
                }

                Monitor.Pulse(this.updateLock);
            }
        }