2 messaggi dal 15 luglio 2010
Salve a tutti,
sto realizzando un' applicazione con MVC3 che prevede un sitema di aste tipo ebay.

In particolare un utente può creare un' asta che tra i suoi attributi ha:
DataScadenza
OraScadenza
Quando inserisco l'asta nel DB eseguo queste operazioni
DateTime now = DateTime.Now;
                DateTime dateAsta = asta.DataScadenza.
                    AddHours(Convert.ToDouble(asta.OraScadenza.Split(",".ToCharArray())[0])).
                    AddMinutes(Convert.ToDouble(asta.OraScadenza.Split(",".ToCharArray())[1]));
TimeSpan duration = dateAsta.Subtract(now).Duration();
System.Timers.Timer timer = new System.Timers.Timer(duration.TotalMilliseconds);
                    asta.TimerHashCode = timer.GetHashCode();
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
                    timer.AutoReset = false;
                    timer.Enabled = true;
                    GC.KeepAlive(timer);


Gestore evento Elapsed

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                using (MioContext context = new MioContext())
                {
                    int hc = sender.GetHashCode();
                    Asta asta = context.AstaSet.SingleOrDefault(x => x.TimerHashCode == hc);
                 .......
                }
            }
            catch (Exception ex)
            {
                LoggerWrapper.Write("AstaManager.timer_Elapsed", ex, NLog.LogLevel.Error);
            }
        }

  • Vorrei sapere innanzitutto se questa tecnica è giusta o se ci sono pattern per questa problematica.

  • Poi vorrei sapere come comportarmi per gli aggiornamenti(shutdown e restart) dell'applicazione,che comportano la perdita di tutti i riferimenti ai timers.

Grazie in anticipo per le risposte
Michele
ps scusate per i caratteri non codificati!
46 messaggi dal 25 febbraio 2002
Ti consiglierei di registrare gli estremi delle aste in una table 'Alarms' ordinata per data scadenza asta e monitorare con un processo configurabile ad intervalli minimi ( da uno a pochi minuti, dipende dalla criticità dell'evento) il raggiungimento di scadenza.

Non riesco ad immaginare un sistema che per mille aste mantiene in vita mille timers contemporaneamente.

ciao
2 messaggi dal 15 luglio 2010
ciao
intanto grazie per la risposta.

Avevo pensato alla tua soluzione ma volevo evitare di fare una query al minuto sul db perciò ho cercato strade alternative.
Effettivamente neppure quella di avere in memoria migliaia di Timer è una
'Furbata' :)
Pensandoci sono arrivato a qeusta soluzione
public sealed class AlarmsManager:IDisposable
    {
        //Intervallo lettura default 1min
        int interval = 60000;
        Timer timer = null;
        private static Dictionary<int, DateTime> inCorsoItems = null;
        private static Dictionary<int, DateTime> chiusiItems = null;
        static readonly AlarmsManager _instance = new AlarmsManager();
        public static AlarmsManager Instance
        {
            get
            {
                return _instance;
            }
        }
        private AlarmsManager()
        {
            if (ConfigurationManager.AppSettings["AlarmsManagerInterval"] != null)
                interval = Convert.ToInt32(ConfigurationManager.AppSettings["AlarmsManagerInterval"]);
            inCorsoItems = new Dictionary<int, DateTime>();
            chiusiItems = new Dictionary<int, DateTime>();
            if (!IsConfiguredFromXml())
                Start();
        }
        public void AddNewInCorso(int astaID, DateTime scadenza)
        {
            inCorsoItems.Add(astaID, scadenza);
        }
        private void Start()
        {
            timer = new Timer(interval);
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Enabled = true;
        }
        public void StopAndWriteObserved()
        {
            //Scrivo su un file xml tutte le aste in sospeso
            //mi serve in caso Application_Stop
        }
        public bool IsConfiguredFromXml()
        {
            //Leggo il file xml e reimposto tutte le scadenza
            //se trovo aste scadute Update
            //Problema potrebbe passare troppo tempo e la chiusura avverrebbe con un ritardo
            return false;
        }
        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            var changedList = from item in inCorsoItems
                              where item.Value <= DateTime.Now
                              select item;
            var daCancellare = from todel in chiusiItems
                               where todel.Value <= DateTime.Now
                               select todel;
            foreach (var item in changedList)
            {
                AstaManager astaManager = new AstaManager();
                astaManager.UpdateStato(item.Key);
                chiusiItems.Add(item.Key, DateTime.Now.AddDays(1));
                inCorsoItems.Remove(item.Key);
            }
            foreach (var todel in daCancellare)
            {
                AstaManager astaManager = new AstaManager();
                astaManager.CancellaAsta(todel.Key);
                chiusiItems.Remove(todel.Key);
            }
        }

        #region IDisposable Membri di

        public void Dispose()
        {
            StopAndWriteObserved();
        }

        #endregion
    }


L'unico problema è il tempo che potrebbe trascorrere tra lo shutdown dell'App ed il restart.
Accetto suggerimenti sulla soluzione.
Michele
46 messaggi dal 25 febbraio 2002
Bella la soluzione, devi prevenire lo stato di off-line del servizio.
Il mio caso reale ( eventi di booking turistico ) parte dallo schedulatore di task di Windows che ogni 3 minuti ( sono sufficienti per me ) invoca tramite jscript un metodo di un webservice (Poller) che si incarica di eseguire una query ( velocissima ) sugli eventi scaduti ( quindi recupera anche eventuali fermi macchina precedenti ).
Se la chiamata al webservice rileva un errore, forza addirittura il riavvio di iis ( a volte , raramente, è successo ) per garantire il servizio.
Ciao

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.