Esempio n. 1
0
        // Dequeue the next file, load it as a BitmapImage, and return it. If there is no file, store the callback and dispatcher, to be called when the next file is enqueued.
        // If a file is under review, it will NOT be passed to the next module; it will silently exit the workflow.
        public ImageSource NextImage(NextImageCallback callback, System.Windows.Threading.Dispatcher dispatcher)
        {
            // TODO Consider reusing the dispatcher from BasicModule, which was added as part of logging.
            ImageSource returnValue = null;
            bool        gotLock     = false;

            while (!gotLock)
            {
                fileLock.Enter(ref gotLock);
            }

            // We have the lock.

            // Clear any saved callbacks; this request overrides them.
            nextImageCallback           = null;
            nextImageCallbackDispatcher = null;

            if (files.Count > 0)
            {
                // Great! We can dequeue.

                FileInfo file;

                // Get the next file to process.
                file = files.Dequeue();

                log($"ImageReviewer.NextImage: Dequeued file: {file.FullName}");

                // Save the file so we have it when the decision to accept/reject comes back.
                fileUnderReview = file;
                fileLock.Exit();

                // Load the image, AFTER exiting.
                try
                {
                    returnValue = makeImage(file);
                }
                catch (Exception e)
                {
                    log($"ImageReviewer.NextImage: makeImage threw exception: {e.Message}");
                    log("ImageReviewer.NextImage: Ignoring this image and recursing.");
                    returnValue = NextImage(callback, dispatcher);
                }
            }
            else
            {
                // Nothing to dequeue. Save a callback.

                nextImageCallback           = callback;
                nextImageCallbackDispatcher = dispatcher;

                fileLock.Exit();

                // And clear the current saved file.
                fileUnderReview = null;

                log($"ImageReviewer.NextImage: Nothing to dequeue. Saved callback.");
            }
            return(returnValue);
        }
Esempio n. 2
0
        private void enqueue(FileInfo file)
        {
            bool gotLock = false;

            while (!gotLock)
            {
                fileLock.Enter(ref gotLock);
            }

            // We have the lock.

            files.Enqueue(file);

            if (nextImageCallback != null)
            {
                // Someone's waiting. Hand the image straight to them.

                // First, let's take care of the work that must be locked.
                // We'll save a copy of the callback and clear the shared memory.
                NextImageCallback callback   = nextImageCallback;
                Dispatcher        dispatcher = nextImageCallbackDispatcher;
                nextImageCallback           = null;
                nextImageCallbackDispatcher = null;

                // Save the file since it's being reviewed.
                fileUnderReview = file;

                fileLock.Exit();

                log($"ImageReviewer.enqueue: Enqueued and invoking callback for: {file.FullName}");

                // Now we do the real work: make a new BitmapImage and pass it on.
                dispatcher.Invoke(() => callback());
            }
            else
            {
                // We're just enqueueing in the background. Nothing more to do.
                fileLock.Exit();

                log($"ImageReviewer.enqueue: Enqueued: {file.FullName}");
            }
        }