Example #1
0
        /// <summary>
        /// Método que controla el fin de la ejecución de un proceso en segundo plano
        /// </summary>
        /// <param name="stickyId">Identificador del plan de ejecución</param>
        /// <param name="e">Argumentos del evento de fin de ejecución</param>
        /// <param name="work">Proceso en segundo plano</param>
        private static void EndWorkExecution(long stickyId, DoWorkEventArgs e, BackgroundWorker work = null)
        {
            Hal.Results[stickyId] = e.Result;

            //Comprobamos si el trabajo es periodico
            if (!StickyUtils.GetStickyProp <bool>(e.Argument, "IsPeriodic"))
            {
                //Finalizamos la ejecución del trabajo
                RemoveWork(stickyId);

                if (work != null)
                {
                    lock (Hal.KingHill)
                    {
                        Hal.KingHill.ReleasePriority(work.GetHashCode().ToString(CultureInfo.InvariantCulture));
                    }
                }
            }
            else
            {
                //Pausamos el trabajo y lo volvemos a ejecutar de nuevo
                Thread.Sleep(StickyUtils.GetStickyProp <int>(e.Argument, "MillisecondsDelay"));

                var newWork = CreateWork();
                newWork.RunWorkerAsync(e.Argument);
            }
        }
Example #2
0
        /// <summary>
        /// Método que gestiona el evento de ejecución de un proceso en segundo plano
        /// </summary>
        /// <param name="sender">Proceso en segundo plano</param>
        /// <param name="e">Argumentos del evento</param>
        private static void BwDoWork(object sender, DoWorkEventArgs e)
        {
            //Obtenemos los datos del trabajo
            long id = StickyUtils.GetStickyId(e.Argument);

            var worker = sender as BackgroundWorker;

            //Comprobamos si hay una cancelación pendiente del trabajo
            if (worker != null && worker.CancellationPending)
            {
                e.Cancel = true;
                RemoveWork(id);

                return;
            }

            var isCacheable = StickyUtils.GetStickyProp <bool>(e.Argument, "IsCacheable");

            //Comprobamos si se quiere utilizar la cache
            if (isCacheable)
            {
                var hash = StickyUtils.GetStickyProp <string>(e.Argument, "Hash");

                //Comprobamos si el resultado ya se encuentra en cache
                if (SonarCache.ContainsKey(hash))
                {
                    e.Result = SonarCache[hash];
                }
                else
                {
                    //En caso contrario calculamos y guardamos en cache
                    e.Result = StickyUtils.ExecuteSticky(e.Argument, worker);

                    SonarCache[hash] = e.Result;
                }
            }
            else
            {
                //Ejecución normal de trabajos sin cache
                e.Result = StickyUtils.ExecuteSticky(e.Argument, worker);
            }

            EndWorkExecution(id, e, worker);
        }
Example #3
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);
            }
        }