Combinando più eventi in un'unica azione / Rinvia aggiornamento

4

Quindi in un programma della GUI ho più eventi che attivano un aggiornamento di uno spazio di lavoro. Questa chiamata di aggiornamento è costosa quindi vorrei che non accadesse molto spesso.

Un utente potrebbe scegliere qualcosa da un menu a discesa (attiva un aggiornamento) e quindi inserire un segno di spunta in una casella di controllo (attiva anche un aggiornamento). Se lo fa in un breve intervallo di tempo, questo potrebbe comportare che il primo aggiornamento sia irrilevante.

Un modo per gestirlo sarebbe avere un pulsante di aggiornamento da premere o un interruttore per impostare se aggiornare automaticamente. Ma non vorrei metterlo nelle mani dell'utente.

C'è qualche altra strategia per fare ciò che si è dimostrato efficace e privo di errori?

PS. Sto specificatamente usando .Net 4.0 - > C # - > WPF - > Caliburn.Micro ma vorrebbe conoscere qualsiasi metodo che possa essere riprodotto usando .net 4

    
posta Ingó Vals 24.08.2012 - 15:04
fonte

3 risposte

4

Ho una classe per questo scopo e ne ho scritto un blog qui .

All'inizializzazione di ViewModel:

DeferredUpdater m_Updater = new DeferredUpdater(TimeSpan.FromSeconds(3),    //The amount of time between two updates that has to pass for an update in database to be required
                                                TimeSpan.FromSeconds(0.5), //The polling time
                                                OnUpdateRequested);           //The callback to use to update in database.

E dovrai collegare l'evento propertychanged del tuo viewmodel:

this.PropertyChanged += OnPropertyChanged;
void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{   
   m_Updater.DeferUpdate();
}

E, naturalmente, definire la callback:

void OnUpdateRequested()
{
   //Call to DAL/database.
}

Rinvia l'aggiornamento controllando ogni X quantità di tempo se è trascorso l'intervallo di tempo Y dall'ultima chiamata a DeferUpdate e fa tutto ciò in una discussione (tramite un'attività).

Per quanto ne so (l'ho provato molto e lo uso in uno scenario di produzione) è sicuro per i thread.

Assicurati di avere l'ultima versione (V2) che è una soluzione migliorata.

    
risposta data 24.08.2012 - 18:14
fonte
9

Un modo per evitare di aggiornare troppo spesso sarebbe utilizzare un dirty_flag + un timer; imposta l'intervallo del timer su qualcosa come 200ms o qualsiasi valore tu consideri ottimale.

Quando si verifica un evento che richiede un aggiornamento, basta impostare dirty_flag su true e reinizializzare il timer (in questo modo si assicura che Timer.Tick venga sollevato in "x" millisecondi dopo l'azione dell'utente). Se un'altra azione viene intrapresa dall'utente in quell'intervallo di tempo, si reinizializza nuovamente il timer e così via.

Quindi, su Timer.Tick: fai il refresh solo se dirty_flag = true, set dirty_flag = false.

Un'ottimizzazione che puoi fare è disabilitare il Timer dopo l'aggiornamento e abilitarlo nella prossima azione che richiede un aggiornamento.

    
risposta data 24.08.2012 - 15:38
fonte
1

Se il tuo aggiornamento è non-bloccante potresti forse aggiungere una cancellazione. Quando un aggiornamento si sovrappone a un altro aggiornamento, innanzitutto annulla l'aggiornamento precedente e ne invochi uno nuovo.

Se l'aggiornamento è veramente costoso, forse puoi localizzarlo un po 'di più. Il drop-down ha effetto su tutto o potresti indirizzare logicamente un sottoinsieme di stato presentato?

    
risposta data 24.08.2012 - 16:38
fonte

Leggi altre domande sui tag