Ejemplo n.º 1
0
        /// <summary>
        /// Método que gestiona el evento de fin de ejecución de un proceso en segundo plano
        /// </summary>
        /// <param name="sender">Origen del evento</param>
        /// <param name="e">Resultado de la ejecución del proceso en segundo plano</param>
        private static void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var work = sender as BackgroundWorker;

            if (work != null)
            {
                string wHash = work.GetHashCode().ToString(CultureInfo.InvariantCulture);

                //Comprobamos si el proceso tenía otros subprocesos cacheables pendientes de su ejecución
                //Y en caso de ser así asignamos a todos el mismo resultado
                if (IndexDependencies.ContainsKey(wHash))
                {
                    string stHash = IndexDependencies[wHash];

                    lock (CacheDependencies)
                    {
                        IList <long> stickiesDep = CacheDependencies[stHash];

                        foreach (var stickyId in stickiesDep)
                        {
                            RemoveWork(stickyId);

                            if (!e.Cancelled && e.Error == null)
                            {
                                Hal.Results[stickyId] = e.Result;
                            }
                        }

                        CacheDependencies.Remove(stHash);
                        IndexDependencies.Remove(wHash);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Ejecuta un proceso en segundo plano
        /// </summary>
        /// <typeparam name="T">Tipo de parámetro del delegado a invocar</typeparam>
        /// <param name="sticky">Plan de ejecución</param>
        private static void RunWork <T>(Sticky <T> sticky)
        {
            var    work  = CreateWork();
            string wHash = work.GetHashCode().ToString(CultureInfo.InvariantCulture);

            Hal.Sonar.Add(sticky.Id, work);

            //Se comprueba si en el plan de ejecución se tiene en cuenta el cacheo
            if (sticky.IsCacheable)
            {
                lock (CacheDependencies)
                {
                    if (!CacheDependencies.ContainsKey(sticky.Hash))
                    {
                        //Creamos el proceso maestro que servirá de referencia para los demás
                        CacheDependencies[sticky.Hash] = new List <long>();
                        IndexDependencies[wHash]
                            = sticky.Hash;
                    }
                    else
                    {
                        CacheDependencies[sticky.Hash].Add(sticky.Id);

                        return;
                    }
                }
            }

            //Comprobamos si el nuevo proceso es el más prioritario
            if (Hal.KingHill == null)
            {
                Hal.KingHill = new KingHill(wHash, sticky.PriorityPercent);
            }
            else
            {
                lock (Hal.KingHill)
                {
                    Hal.KingHill.AddWorker(wHash, sticky.PriorityPercent);
                }
            }


            //Ejecutamos el trabajo
            work.RunWorkerAsync(sticky);
        }
Ejemplo n.º 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);
            }
        }