private bool DoWorkFrom( ConcurrentDictionary <ITransferController, object> activeItems) { // Filter items with work only. List <KeyValuePair <ITransferController, object> > activeItemsWithWork = new List <KeyValuePair <ITransferController, object> >( activeItems.Where(item => item.Key.HasWork && !item.Key.IsFinished)); if (0 != activeItemsWithWork.Count) { // Select random item and get work delegate. int idx = this.randomGenerator.Next(activeItemsWithWork.Count); ITransferController transferController = activeItemsWithWork[idx].Key; if (Interlocked.Increment(ref this.ongoingTasks) <= TransferManager.Configurations.ParallelOperations) { DoControllerWork(transferController); return(true); } else { Interlocked.Decrement(ref this.ongoingTasks); return(false); } } return(false); }
private void FillInQueue( ConcurrentDictionary <ITransferController, object> activeItems, BlockingCollection <ITransferController> collection, CancellationToken token) { while (!token.IsCancellationRequested && Interlocked.Read(ref this.activeControllerItemCount) < MaxActiveControllerItemCount) { ITransferController transferItem = null; try { if (!collection.TryTake(out transferItem) || null == transferItem) { return; } } catch (ObjectDisposedException) { return; } if (activeItems.TryAdd(transferItem, null)) { Interlocked.Increment(ref this.activeControllerItemCount); } } }
private void FinishedWorkItem( ITransferController transferController) { object dummy; this.activeControllerItems.TryRemove(transferController, out dummy); }
private void FillInQueue( ConcurrentDictionary <ITransferController, object> activeItems, BlockingCollection <ITransferController> collection, CancellationToken token) { while (!token.IsCancellationRequested && activeItems.Count < this.transferOptions.ParallelOperations) { if (activeItems.Count >= this.transferOptions.ParallelOperations) { return; } ITransferController transferItem = null; try { if (!collection.TryTake(out transferItem) || null == transferItem) { return; } } catch (ObjectDisposedException) { return; } activeItems.TryAdd(transferItem, null); } }
private void FinishedWorkItem( ITransferController transferController) { object dummy; if (this.activeControllerItems.TryRemove(transferController, out dummy)) { Interlocked.Decrement(ref this.activeControllerItemCount); } }
private async void DoControllerWork(ITransferController controller) { this.scheduleSemaphore.Wait(); bool finished = await controller.DoWorkAsync(); this.scheduleSemaphore.Release(); if (finished) { this.FinishedWorkItem(controller); } }
private bool DoWorkFrom( ConcurrentDictionary <ITransferController, object> activeItems) { // Filter items with work only. // TODO: Optimize scheduling efficiency, get active items with LINQ cost a lot of time. List <KeyValuePair <ITransferController, object> > activeItemsWithWork = new List <KeyValuePair <ITransferController, object> >( activeItems.Where(item => item.Key.HasWork && !item.Key.IsFinished)); int scheduledItemsCount = 0; // In order to save time used to lock/search/addItem ConcurrentDictionary, try to schedule multipe items per DoWorkFrom round. while (0 != activeItemsWithWork.Count && scheduledItemsCount < MaxControllerItemCountToScheduleEachRound) { // Select random item and get work delegate. int idx = this.randomGenerator.Next(activeItemsWithWork.Count); ITransferController transferController = activeItemsWithWork[idx].Key; var scheduledOneItem = false; while (!scheduledOneItem) { // Note: TransferManager.Configurations.ParallelOperations could be a changing value. if (Interlocked.Increment(ref this.ongoingTasks) <= TransferManager.Configurations.ParallelOperations) { // Note: This is the only place where ongoing task could be scheduled. this.DoControllerWork(transferController); scheduledItemsCount++; activeItemsWithWork.RemoveAt(idx); scheduledOneItem = true; } else { Interlocked.Decrement(ref this.ongoingTasks); this.ongoingTaskEvent.Wait(); this.ongoingTaskEvent.Reset(); } } } if (scheduledItemsCount > 0) { return(true); } else { return(false); } }
private void FillInQueue( ConcurrentDictionary <ITransferController, object> activeItems, BlockingCollection <ITransferController> collection, CancellationToken token) { while (!token.IsCancellationRequested && Interlocked.Read(ref this.activeControllerItemCount) < MaxActiveControllerItemCount) { ITransferController transferItem = null; try { if (this.activeControllerItemCount <= 0) { transferItem = collection.Take(this.cancellationTokenSource.Token); if (null == transferItem) { return; } } else { if (!collection.TryTake(out transferItem) || null == transferItem) { return; } } } catch (OperationCanceledException) { return; } catch (InvalidOperationException) { // This kind of exception will be thrown when the BlockingCollection is marked as complete for adding, or is disposed. return; } if (activeItems.TryAdd(transferItem, null)) { Interlocked.Increment(ref this.activeControllerItemCount); } } }
private async void DoControllerWork(ITransferController controller) { bool finished = false; try { finished = await controller.DoWorkAsync(); } finally { Interlocked.Decrement(ref this.ongoingTasks); } if (finished) { this.FinishedWorkItem(controller); } }
private bool DoWorkFrom( ConcurrentDictionary <ITransferController, object> activeItems) { // Filter items with work only. List <KeyValuePair <ITransferController, object> > activeItemsWithWork = new List <KeyValuePair <ITransferController, object> >( activeItems.Where(item => item.Key.HasWork && !item.Key.IsFinished)); if (0 != activeItemsWithWork.Count) { // Select random item and get work delegate. int idx = this.randomGenerator.Next(activeItemsWithWork.Count); ITransferController transferController = activeItemsWithWork[idx].Key; DoControllerWork(transferController); return(true); } return(false); }
public ITransferControllerTest() { _transferReleaseServiceMock = Substitute.For <ITransferService>(); _ITransferController = new TransferController(_transferReleaseServiceMock); }