Пример #1
0
        private static List <string> GenerateTree(
            ICompiledGram gram,
            CircularQueue <string> prior,
            int size,
            int index,
            List <string> acceptedTypes,
            Func <string, string> classifier)
        {
            string[] guesses = gram.GetGuesses(prior.ToArray());
            foreach (string guess in guesses)
            {
                if (classifier != null &&
                    !classifier(guess).Equals(acceptedTypes[index]))
                {
                    continue;
                }

                CircularQueue <string> newPrior = prior.Clone();
                newPrior.Add(guess);

                if (size <= 1)
                {
                    return(new List <string>()
                    {
                        guess
                    });
                }
                else if (gram.HasNextStep(newPrior.ToArray()))
                {
                    List <string> returnVal = GenerateTree(
                        gram,
                        newPrior,
                        size - 1,
                        index + 1,
                        acceptedTypes,
                        classifier);

                    if (returnVal != null)
                    {
                        returnVal.Insert(0, guess);
                        return(returnVal);
                    }
                }
            }

            return(null);
        }
        /// <summary>Initializes the scheduler.</summary>
        /// <param name="threadOnCpu">how many threads will be created per cpu. recommanded is 1 or 2.</param>
        /// <param name="cpusPerThread">When creating a thread, on how many cpus should it be distributed on? When there are: 4 cpus, <paramref name="threadCount"/> is 4 then each thread will be assinged into two cpus. thread1 to cpu1 and cpu2, thread2 to cpu2 and cpu3, thread 3 to cpu3 and cpu4, thread 4 to cpu4 and cpu1.</param>
        public DistributedQueuedTaskScheduler(int cpusPerThread, int threadOnCpu, int cpus = -1, string threadName = "", ThreadPriority threadPriority = ThreadPriority.Normal, ApartmentState threadApartmentState = ApartmentState.MTA, int threadMaxStackSize = 0, Action threadInit = null, Action threadFinally = null, CancellationToken?cancellationToken = null)
        {
            if (cpusPerThread <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(cpusPerThread));
            }
            if (threadOnCpu <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(threadOnCpu));
            }
            if (cpus < 0)
            {
                cpus = Environment.ProcessorCount;
            }

            var threadCount = threadOnCpu * cpus;

            var threads = new DistributedThread[threadCount];

            for (int i = 0; i < threadCount; i++)
            {
                threads[i] = new DistributedThread(() => ThreadBasedDispatchLoop(threadInit, threadFinally), threadMaxStackSize)
                {
                    Priority     = threadPriority,
                    IsBackground = true,
                    Name         = $"[{(threadName ?? "QWorker ")}] {i}"
                };

                threads[i].SetApartmentState(threadApartmentState);
            }

            var possibleAffinities = new CircularQueue <int>();

            for (int i = 0; i < cpus; i++)
            {
                //popular
                possibleAffinities.Enqueue(1 << i);
            }

            for (int i = 0; i < threadCount; i++)
            {
                var thread = threads[i];
                thread.ProcessorAffinity = 0;
                var clone = (CircularQueue <int>)possibleAffinities.Clone();
                possibleAffinities.Dequeue(); //move forward by one
                for (int x = 0; x < cpusPerThread; x++)
                {
                    thread.ProcessorAffinity |= clone.Dequeue();
                }
            }

            _disposeCancellation = new CancellationTokenSource();
            _sharedCancellation  = cancellationToken.HasValue ? CancellationTokenSource.CreateLinkedTokenSource(_disposeCancellation.Token, cancellationToken.Value) : _disposeCancellation;

            _concurrencyLevel = threadCount;

            // Initialize the queue used for storing tasks
            _blockingTaskQueue = new BlockingCollection <Task>();

            _threads = new Thread[threadCount];
            for (var i = 0; i < threads.Length; i++)
            {
                var dt = threads[i];
                dt.Start();
                _threads[i] = dt.ManagedThread;
            }
        }