public BackgroundDispatcherAsync( [NotNull] IBackgroundExecution execution, [NotNull] Func <Guid, object, Task> action, [CanBeNull] object state, [NotNull] TaskScheduler taskScheduler, int maxConcurrency, bool ownsScheduler) { if (maxConcurrency <= 0) { throw new ArgumentOutOfRangeException(nameof(maxConcurrency)); } _execution = execution ?? throw new ArgumentNullException(nameof(execution)); _action = action ?? throw new ArgumentNullException(nameof(action)); _state = state; _taskScheduler = taskScheduler ?? throw new ArgumentNullException(nameof(taskScheduler)); _ownsScheduler = ownsScheduler; #if !NETSTANDARD1_3 AppDomainUnloadMonitor.EnsureInitialized(); #endif _stopped = new CountdownEvent(maxConcurrency); for (var i = 0; i < maxConcurrency; i++) { Task.Factory.StartNew( DispatchLoop, CancellationToken.None, TaskCreationOptions.None, _taskScheduler).Unwrap(); } }
public BackgroundExecution(CancellationToken stopToken, [NotNull] BackgroundExecutionOptions options) { _options = options ?? throw new ArgumentNullException(nameof(options)); _logger = LogProvider.GetLogger(GetType()); _createdAt = Stopwatch.StartNew(); _stopToken = stopToken; _stopRegistration = _stopToken.Register(SetStoppedAt); #if !NETSTANDARD1_3 AppDomainUnloadMonitor.EnsureInitialized(); #endif }
/// <summary>Initializes a new instance of the <see cref="BackgroundTaskScheduler"/> /// class with the specified <paramref name="threadFactory"/> and an optional exception /// handler. All the created threads will be started to dispatch <see cref="Task"/> /// instances scheduled to run on this scheduler.</summary> /// <param name="threadFactory">Callback that creates one or more dedicated threads.</param> /// <param name="exceptionHandler">Optional callback that is invoked when unhandled exception occurs /// in one of the threads. After this event this instance is considered stopped.</param> /// <exception cref="ArgumentNullException"><paramref name="threadFactory"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="threadFactory"/> returned <see langword="null"/> or zero threads.</exception> /// <exception cref="ArgumentException"><paramref name="threadFactory"/> returned at least one thread not in the <see cref="ThreadState.Unstarted"/> state.</exception> public BackgroundTaskScheduler( [NotNull] Func <ThreadStart, IEnumerable <Thread> > threadFactory, [CanBeNull] Action <Exception> exceptionHandler) { if (threadFactory == null) { throw new ArgumentNullException(nameof(threadFactory)); } _exceptionHandler = exceptionHandler; _semaphore = new Semaphore(0, Int32.MaxValue); // Stopped event should always be the first in this array, see the DispatchLoop method. _waitHandles = new WaitHandle[] { _stopped, _semaphore }; #if !NETSTANDARD1_3 AppDomainUnloadMonitor.EnsureInitialized(); #endif _threads = threadFactory(DispatchLoop)?.ToArray(); if (_threads == null || _threads.Length == 0) { throw new ArgumentException("At least one non-started thread should be created.", nameof(threadFactory)); } if (_threads.Any(thread => thread == null || (thread.ThreadState & ThreadState.Unstarted) == 0)) { throw new ArgumentException("All the threads should be non-null and in the ThreadState.Unstarted state.", nameof(threadFactory)); } foreach (var thread in _threads) { thread.Start(); } _ourThreadIds = new HashSet <int>(_threads.Select(x => x.ManagedThreadId)); }
public BackgroundDispatcher( [NotNull] IBackgroundExecution execution, [NotNull] Action <Guid, object> action, [CanBeNull] object state, [NotNull] Func <ThreadStart, IEnumerable <Thread> > threadFactory) { if (threadFactory == null) { throw new ArgumentNullException(nameof(threadFactory)); } _execution = execution ?? throw new ArgumentNullException(nameof(execution)); _action = action ?? throw new ArgumentNullException(nameof(action)); _state = state; #if !NETSTANDARD1_3 AppDomainUnloadMonitor.EnsureInitialized(); #endif var threads = threadFactory(DispatchLoop)?.ToArray(); if (threads == null || threads.Length == 0) { throw new ArgumentException("At least one unstarted thread should be created.", nameof(threadFactory)); } if (threads.Any(thread => thread == null || (thread.ThreadState & ThreadState.Unstarted) == 0)) { throw new ArgumentException("All the threads should be non-null and in the ThreadState.Unstarted state.", nameof(threadFactory)); } _stopped = new CountdownEvent(threads.Length); foreach (var thread in threads) { thread.Start(); } }