/// <summary> /// Used by the worker thread to process items. /// </summary> private void Run() { while (!Stopping) { lock (lockObject) { // Wait until we have pending work items if (paused || IsWorkQueueEmpty ()) Monitor.Wait (lockObject); } // Loop until we exhaust the queue bool queueFull = true; while (queueFull && !Stopping && !Paused) { // Get an item from the queue AsyncOperation asyncOp = null; object request = null; int priority = 0; lock (lockObject) { // Check queues Utility.Tuple<AsyncOperation, int> work = GetWork (); asyncOp = work.Item1; priority = work.Item2; if (asyncOp != null) request = asyncOp.UserSuppliedState; // Check if the item was removed if (request != null && cancelledItems.ContainsKey (request)) request = null; } if (request != null) { Exception error = null; // Start the work QueuedWorkerDoWorkEventArgs doWorkArg = new QueuedWorkerDoWorkEventArgs (request, priority); try { // Raise the do work event OnDoWork (doWorkArg); } catch (Exception e) { error = e; } // Raise the work complete event QueuedWorkerCompletedEventArgs workCompletedArg = new QueuedWorkerCompletedEventArgs (request, doWorkArg.Result, priority, error, doWorkArg.Cancel); if (!Stopping) asyncOp.PostOperationCompleted (workCompletedCallback, workCompletedArg); } else if (asyncOp != null) asyncOp.OperationCompleted (); // Check if the cache is exhausted lock (lockObject) { queueFull = !IsWorkQueueEmpty (); } } } }
/// <summary> /// Raises the RunWorkerCompleted event. /// </summary> /// <param name="e">A <see cref="QueuedWorkerCompletedEventArgs"/> that contains event data.</param> protected virtual void OnRunWorkerCompleted(QueuedWorkerCompletedEventArgs e) { if (RunWorkerCompleted != null) RunWorkerCompleted (this, e); }
/// <summary> /// Handles the RunWorkerCompleted event of the queued background worker. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="ImageGlass.ImageListView.QueuedWorkerCompletedEventArgs"/> /// instance containing the event data.</param> void bw_RunWorkerCompleted(object sender, QueuedWorkerCompletedEventArgs e) { CacheRequest request = e.UserState as CacheRequest; CacheItem result = e.Result as CacheItem; // We are done processing if (request.RequestType == RequestType.Renderer) processingRendererItem = Guid.Empty; else if (request.RequestType == RequestType.Gallery) processingGalleryItem = Guid.Empty; else processing.Remove(request.Guid); // Do not process the result if the cache operation // was cancelled. if (e.Cancelled) return; // Dispose old item and add to cache if (request.RequestType == RequestType.Renderer) { if (rendererItem != null) rendererItem.Dispose(); rendererItem = result; } else if (request.RequestType == RequestType.Gallery) { if (galleryItem != null) galleryItem.Dispose(); galleryItem = result; } else if (result != null) { CacheItem existing = null; if (thumbCache.TryGetValue(result.Guid, out existing)) { existing.Dispose(); thumbCache.Remove(result.Guid); } thumbCache.Add(result.Guid, result); if (result.Image != null) { // Did the thumbnail size change while we were // creating the thumbnail? if (result.Size != mImageListView.ThumbnailSize) result.State = CacheState.Unknown; // Purge invisible items if we exceeded the cache limit MemoryUsed += GetImageMemorySize(result.Image); if (IsCacheLimitExceeded()) PurgeInvisible(true); } } //Refresh the control if (mImageListView != null) { if (request.RequestType != RequestType.Thumbnail || mImageListView.IsItemVisible(request.Guid)) mImageListView.Refresh(false, true); } // Raise the ThumbnailCached event if (mImageListView != null) mImageListView.OnThumbnailCachedInternal(result.Guid, result.Image, result.Size, request.RequestType == RequestType.Thumbnail); // Raise the CacheError event if (e.Error != null && mImageListView != null) mImageListView.OnCacheErrorInternal(result.Guid, e.Error, CacheThread.Thumbnail); }
/// <summary> /// Handles the RunWorkerCompleted event of the queued background worker. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="ImageGlass.ImageListView.QueuedWorkerCompletedEventArgs"/> /// instance containing the event data.</param> void bw_RunWorkerCompleted(object sender, QueuedWorkerCompletedEventArgs e) { CacheRequest request = e.UserState as CacheRequest; // We are done processing processing.Remove (request.Guid); // Do not process the result if the cache operation // was cancelled. if (e.Cancelled) return; // Get result Utility.Tuple<ColumnType, string, object>[] details = (Utility.Tuple<ColumnType, string, object>[])e.Result; if (details != null && mImageListView != null) { mImageListView.UpdateItemDetailsInternal(request.Guid, details); } // Refresh the control lazily if (mImageListView != null && mImageListView.IsItemVisible (request.Guid)) mImageListView.Refresh (false, true); // Raise the CacheError event if (e.Error != null && mImageListView != null) mImageListView.OnCacheErrorInternal (request.Guid, e.Error, CacheThread.Details); }
/// <summary> /// Handles the RunWorkerCompleted event of the queued background worker. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="ImageGlass.ImageListView.QueuedWorkerCompletedEventArgs"/> /// instance containing the event data.</param> void bw_RunWorkerCompleted(object sender, QueuedWorkerCompletedEventArgs e) { CacheItem result = e.Result as CacheItem; // We are done processing processing.Remove (result.Extension); // Add to cache if (result != null) { CacheItem existing = null; if (shellCache.TryGetValue (result.Extension, out existing)) { existing.Dispose (); shellCache.Remove (result.Extension); } shellCache.Add (result.Extension, result); } // Refresh the control lazily if (result != null && mImageListView != null) mImageListView.Refresh (false, true); }