Exemplo n.º 1
0
        /// <summary>s
        /// Ejecuta un proceso en segundo plano o lo coloca en la cola de ejecución
        /// en caso de no quedar ningún hilo libre
        /// </summary>
        /// <typeparam name="T">Tipo de parámetro del delegado a invocar</typeparam>
        /// <param name="sticky">Plan de ejecución</param>
        /// <param name="forceExecution">Indica que se ejecuta sin tener en cuenta el número de procesos en ejecución</param>
        /// <param name="exeCxt">Contexto de ejecución </param>
        /// <returns>Identificador del plan de ejecución</returns>
        public static long AddWork <T>(Sticky <T> sticky, bool forceExecution, ExecutionContext <T> exeCxt)
        {
            //Iniciamos el sonar si no estaba activo
            if (Hal.Sonar == null)
            {
                Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;

                Hal.Sonar   = new Dictionary <long, BackgroundWorker>(Hal.MaxParallelsProcess + 5);
                Hal.Results = new Dictionary <long, object>(Hal.MaxParallelsProcess + 5);

                SonarProgress = new Dictionary <long, int>();
                SonarCache    = new Dictionary <string, object>();

                ProcessInQueue      = new Queue <object>();
                ProcessInQueueIndex = new List <long>();

                CacheDependencies = new Dictionary <string, IList <long> >();
                IndexDependencies = new Dictionary <string, string>();
            }

            if (exeCxt != null)
            {
                exeCxt.AttachWork(sticky, forceExecution);
                return(-1);
            }

            //Asignamos un ticket de ejecución al trabajo
            sticky.Id = Hal.GetTicket();

            //Creamos el trabajo y lo ejecutamos si no excede
            //el limite de hilos en ejecución o es prioritario
            if (Hal.Sonar.Count < Hal.MaxParallelsProcess || forceExecution)
            {
                RunWork(sticky);
            }
            else
            {
                //Si hay demasiados trabajos en paralelo
                //se encola para su futura ejecución
                ProcessInQueue.Enqueue(sticky);
                ProcessInQueueIndex.Add(sticky.Id);
            }

            return(sticky.Id);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Elimina un proceso en segundo plano por su identificador
        /// </summary>
        /// <param name="stickyId">Identificador del plan de ejecución</param>
        public static void RemoveWork(long stickyId)
        {
            //Comprobamos si aún existe en el contexto de ejecución
            if (!Hal.Sonar.ContainsKey(stickyId))
            {
                return;
            }

            //Obtenemos el trabajo y lo borramos
            var work = Hal.Sonar[stickyId];

            work.CancelAsync();

            Hal.Sonar.Remove(stickyId);

            //Obtenemos el próximo trabajo en cola y lo ejecutamos

            object sticky = null;

            //Bloqueamos el acceso a la cola para impedir que los
            //diferentes hilos inicien el mismo trabajo
            lock (ProcessInQueue)
            {
                if (ProcessInQueue.Count > 0)
                {
                    sticky = ProcessInQueue.Dequeue();
                }
            }

            //Si existe algún trabajo en cola lo ejecutamos en el sonar
            if (sticky != null)
            {
                long id   = StickyUtils.GetStickyId(sticky);
                var  hash = StickyUtils.GetStickyProp <string>(sticky, "Hash");

                work = CreateWork();
                string wHash = work.GetHashCode().ToString(CultureInfo.InvariantCulture);

                Hal.Sonar.Add(id, work);

                if (StickyUtils.GetStickyProp <bool>(sticky, "IsCacheable"))
                {
                    lock (CacheDependencies)
                    {
                        if (!CacheDependencies.ContainsKey(hash))
                        {
                            CacheDependencies[hash] = new List <long>();
                            IndexDependencies[wHash]
                                = hash;
                        }
                        else
                        {
                            CacheDependencies[hash].Add(id);

                            return;
                        }
                    }
                }

                var priorPer = StickyUtils.GetStickyProp <int>(sticky, "PriorityPercent");

                if (Hal.KingHill == null)
                {
                    Hal.KingHill = new KingHill(wHash, priorPer);
                }
                else
                {
                    lock (Hal.KingHill)
                    {
                        Hal.KingHill.AddWorker(wHash, priorPer);
                    }
                }

                //Ejecutamos el trabajo
                work.RunWorkerAsync(sticky);
            }
        }