Architettura dell'applicazione WPF

1

Ho scritto un'app WPF che sta iniziando a soffrire. Non c'è un modo reale di aggiungere nuove funzionalità nel suo stato attuale, è diventato lento da usare. Questa applicazione è stata avviata come demo e purtroppo è stata venduta e successivamente ampliata (sigh).

All'inizio era solo un sacco di codice tutto su Main. È stato rapidamente messo insieme per dimostrare un concetto. L'applicazione effettua chiamate API e raccoglie dati una volta al secondo, i dati vengono quindi visualizzati sull'interfaccia utente in una serie di fantastici widget.

Chiamare l'API dal thread principale una volta al secondo bloccava l'interfaccia utente. Quindi questo è stato spostato in un BackgroundWorker.

Nel tentativo di separare il codice, UserControls è stato creato per ogni widget e Main è ora un'aggregazione di quelli. BackgroundWorker raccoglie i dati dall'API e li invia ai widget per aggiornare l'interfaccia utente.

A causa di BackgroundWorker, non è possibile aggiornare direttamente gli UserControls (non è possibile accedere ai controlli da un thread diverso) e tutto utilizza il Dispatcher. Il buffer del Dispatcher viene aggiunto a una velocità maggiore di quella che l'UI può aggiornare e i dati visualizzati presto non sono sincronizzati e stai guardando le vecchie informazioni mentre l'app è occupata a scricchiolare altri nuovi dati e metterli in coda al Dispatcher.

Quale sarebbe un approccio più adatto. Ho alcune idee, ma visto che non sono un esperto del WPF sarei interessato a conoscere i modi migliori per riscrivere / refactare questa app.

    
posta DrLazer 19.04.2017 - 17:27
fonte

2 risposte

5

Se stai usando veramente WPF, dovresti probabilmente considerare l'utilizzo del paradigma di programmazione MVVM.

Innanzitutto, puoi facilmente correggere l'aggiornamento dell'interfaccia utente con la maggior parte delle funzionalità nei collegamenti alle proprietà XAML e C #.

In secondo luogo, offre una suite davvero ampia di modi per spostare le funzionalità e la logica aziendale dall'interfaccia utente e dalla presentazione.

Quindi, tenendo presente questo, hai affermato che stai incontrando il problema di non essere in grado di aggiornare l'interfaccia utente dall'operatore in background. Un problema comune.

Utilizzando le associazioni di proprietà in XAML, l'interfaccia NotifyPropertyChanged del framework WPF, alcuni delegati o gestori di eventi, questo può risolvere questo problema.

Come funziona tutto questo: Hai un'interfaccia utente che associa, diciamo, un testo di testo a una proprietà su una classe ViewModel. Quella proprietà, utilizzando l'interfaccia NotifyPropertyChanged, sarà ciò che viene visualizzato nella casella di testo (presupponendo che si utilizzi l'interfaccia correttamente e così via).

Diciamo che il tuo assistente in background fa alcune cose e vuole aggiornare quella casella di testo. Un modo semplice sarebbe avere il lavoratore in background che esegue una sorta di metodo delegato per aggiornare quella proprietà.

Una volta aggiornata la proprietà, la proprietà attiva l'evento OnPropertyChanged. A sua volta, aggiorna il testo della casella di testo a cui è associato.

Il kicker è, inoltre, un sacco di cose che possono essere legate alle proprietà, non solo al testo.

Spero di indirizzarti nella giusta direzione.

    
risposta data 20.04.2017 - 18:00
fonte
0

Ok, il problema fondamentale qui riguarda le prestazioni del Dispatcher. Se le aggiungi troppo spesso, non può elaborare le richieste tanto velocemente quanto le aggiungi.

Ho trovato questa eccellente risorsa, che dimostra il mio problema in modo conciso e fornisce tre ottime soluzioni che funzionano per me.

link

    
risposta data 22.04.2017 - 11:46
fonte

Leggi altre domande sui tag