[Test] public void TakeReturnsOnlyWhenTaskIsCompleted() { var callable = MockRepository.GenerateMock <ICallable <T> >(); ExpectExecuteCallAndRunTheRunnableInCurrentThread(); _sut.Submit(callable); var f = _sut.Take(); Assert.IsTrue(f.IsDone); callable.AssertWasCalled(c => c.Call()); }
private T DoInvokeAny <T>(IEnumerable tasks, int count, bool timed, TimeSpan durationToWait, Converter <object, IRunnableFuture <T> > converter) { if (tasks == null) { throw new ArgumentNullException("tasks"); } List <IFuture <T> > futures = count > 0 ? new List <IFuture <T> >(count) : new List <IFuture <T> >(); ExecutorCompletionService <T> ecs = new ExecutorCompletionService <T>(this); TimeSpan duration = durationToWait; // For efficiency, especially in executors with limited // parallelism, check to see if previously submitted tasks are // done before submitting more of them. This interleaving // plus the exception mechanics account for messiness of main // loop. try { // Record exceptions so that if we fail to obtain any // result, we can throw the last exception we got. ExecutionException ee = null; DateTime lastTime = (timed) ? DateTime.Now : new DateTime(0); IEnumerator it = tasks.GetEnumerator(); bool hasMoreTasks = it.MoveNext(); if (!hasMoreTasks) { throw new ArgumentException("No tasks passed in."); } futures.Add(ecs.Submit(converter(it.Current))); int active = 1; for (;;) { IFuture <T> f = ecs.Poll(); if (f == null) { if (hasMoreTasks && (hasMoreTasks = it.MoveNext())) { futures.Add(ecs.Submit(converter(it.Current))); ++active; } else if (active == 0) { break; } else if (timed) { f = ecs.Poll(duration); if (f == null) { throw new TimeoutException(); } //TODO: done't understand what are we doing here. Useless!? -K.X. duration = duration.Subtract(DateTime.Now.Subtract(lastTime)); lastTime = DateTime.Now; } else { f = ecs.Take(); } } if (f != null) { --active; try { return(f.GetResult()); } catch (ThreadInterruptedException) { throw; } catch (ExecutionException eex) { ee = eex; } catch (SystemException rex) { ee = new ExecutionException(rex); } } } if (ee == null) { ee = new ExecutionException(); } throw ee; } finally { foreach (IFuture <T> future in futures) { future.Cancel(true); } } }