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; }
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)); } }
public void EnqueueOperation(IOOperation op) { operationQueue.Enqueue(op); lock(statLock) { //Polymorphism FTW. bytesPending += op.EffectiveFileSize; } }
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); }