public WorkerEventLoopGroup(DispatcherEventLoopGroup eventLoopGroup, int nThreads, IThreadFactory threadFactory, IEventExecutorChooserFactory <WorkerEventLoop> chooserFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) { if (eventLoopGroup is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.eventLoopGroup); } if (chooserFactory is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.chooserFactory); } if ((uint)(nThreads - 1) > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_Positive(nThreads, ExceptionArgument.nThreads); } _dispatcherLoop = eventLoopGroup.Dispatcher; PipeName = _dispatcherLoop.PipeName; // Wait until the pipe is listening to connect _dispatcherLoop.WaitForLoopRun(StartTimeout); nThreads = 0u >= (uint)nThreads ? DefaultEventLoopThreadCount : nThreads; _eventLoops = new WorkerEventLoop[nThreads]; var terminationTasks = new Task[nThreads]; for (int i = 0; i < nThreads; i++) { WorkerEventLoop eventLoop = null; bool success = false; try { eventLoop = new WorkerEventLoop(this, threadFactory, rejectedHandler, breakoutInterval); success = eventLoop.ConnectTask.Wait(StartTimeout); if (!success) { ThrowHelper.ThrowTimeoutException(PipeName); } } catch (Exception ex) { ThrowHelper.ThrowInvalidOperationException_CreateChild(ex); } finally { if (!success) { Task.WhenAll(_eventLoops.Take(i).Select(loop => loop.ShutdownGracefullyAsync())).Wait(); } } _eventLoops[i] = eventLoop; terminationTasks[i] = eventLoop.TerminationCompletion; } _chooser = chooserFactory.NewChooser(_eventLoops); TerminationCompletion = Task.WhenAll(terminationTasks); }
/// <summary>Creates a new instance of <see cref="MultithreadEventExecutorGroup{T1, T2}"/>.</summary> protected MultithreadEventExecutorGroup(int nThreads, IEventExecutorChooserFactory <TEventExecutor> chooserFactory, Func <TExecutorGroup, TEventExecutor> eventExecutorFactory) { if (nThreads <= 0) { ThrowHelper.ThrowArgumentException_Positive(nThreads, ExceptionArgument.nThreads); } if (chooserFactory is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.chooserFactory); } if (eventExecutorFactory is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.eventExecutorFactory); } _children = new TEventExecutor[nThreads]; var terminationTasks = new Task[nThreads]; for (int i = 0; i < nThreads; i++) { TEventExecutor eventLoop = null; bool success = false; try { eventLoop = eventExecutorFactory((TExecutorGroup)this); success = true; } catch (Exception ex) { ThrowHelper.ThrowInvalidOperationException_FailedToCreateAChildEventLoop(ex); } finally { if (!success) { Task.WhenAll(_children .Take(i) .Select(loop => loop.ShutdownGracefullyAsync())) .Wait(); } } _children[i] = eventLoop; terminationTasks[i] = eventLoop.TerminationCompletion; } TerminationCompletion = Task.WhenAll(terminationTasks); _chooser = chooserFactory.NewChooser(_children); }