public OperationProgressDetails(IOOperation operation, Exception error)
        {
            Operation = operation;
            this.Error = error;

            ProgressType = error != null ? OperationProgressType.Errored : OperationProgressType.Generic;
        }
        public OperationProgressDetails(IOOperation operation, bool completed)
        {
            Operation = operation;
            Completed = completed;

            ProgressType = completed ? OperationProgressType.Completed : OperationProgressType.Generic;
        }
        public OperationProgressDetails(IOOperation operation, long bytesProcessed, long bytesPending)
        {
            Operation = operation;
            BytesProcessed = bytesProcessed;
            BytesPending = bytesPending;

            ProgressType = OperationProgressType.InProgress;
        }
예제 #4
0
        private void ProcessOperation(IOOperation operation)
        {
            lock (statLock)
                bytesPending -= operation.EffectiveFileSize;

            try
            {
                //Copy operations get some special callbacks and tracking
                OngoingOperation progressOp = operation as OngoingOperation;
                if (progressOp != null)
                {
                    IOProgressCallback copyCall = new IOProgressCallback((pending, transferred, sourceFile, destinationFile) => {
                        OperationProgressDetails details = new OperationProgressDetails(operation, transferred, pending);
                        activeOperations[operation] = details;
                        OnProgress(details);

                        //TODO: potentially add in-file pause to this? Right now we only support one in-file operation: cancel.
                        if (State == OperationState.Terminated)
                            return IOProgressResult.PROGRESS_CANCEL;
                        else
                            return IOProgressResult.PROGRESS_CONTINUE;
                    });
                    progressOp.DoOperation(copyCall);
                }
                else
                {
                    operation.DoOperation();
                }
            }
            catch (Exception e) //We're catching everything (*gasp!*) so we can bubble it up without blowing up stacks of threads.
            {
                OnProgress(new OperationProgressDetails(operation, e));
            }
            finally
            {
                lock(statLock)
                {
                    if (operation.EffectiveFileSize > 0 && activeOperations.ContainsKey(operation))
                        activeOperations.Remove(operation);

                    bytesProcessed += operation.EffectiveFileSize;
                    operationsProcessed += 1;
                }

                //Notify the caller that the operation has completed
                OnProgress(new OperationProgressDetails(operation, true));
            }
        }
예제 #5
0
        public void EnqueueOperation(IOOperation op)
        {
            operationQueue.Enqueue(op);

            lock(statLock)
            {
                //Polymorphism FTW.
                bytesPending += op.EffectiveFileSize;
            }
        }
예제 #6
0
        public void AddOperation(IOOperation op)
        {
            if (State == OperationState.Terminated)
                throw new InvalidOperationException("This OperationManager has been terminated.");

            string root = Path.GetPathRoot(op.FileName);
            string destinationRoot = "";
            if (op is CopyOperation)
            {
                destinationRoot = Path.GetPathRoot(((CopyOperation)op).TransferDestination);
            }
            RootSet roots = new RootSet(root, destinationRoot);

            if (!workers.ContainsKey(roots))
                RegisterWorker(roots);

            workers[roots].EnqueueOperation(op);
        }