UI Applicazioni e operazioni nei thread in background

2

Non sono molto sicuro di quale sia il modo migliore per gestire le operazioni eseguite in background thread in un'applicazione che sto scrivendo.

Lo sto scrivendo in C # e sto seguendo il modello di progettazione MVVM. Alcune azioni dell'utente sono costose e mi piacerebbe eseguirle in un thread in background, che è un approccio abbastanza semplice.

Il thread di lavoro quindi modifica il mio modello, che notifica al ViewModel che qualcosa è cambiato e infine la propagazione viene propagata alla vista.

Il mio problema è che la catena di eventi innescati causerebbe la modifica della vista dal thread in background, quando è consentito solo nel thread dell'interfaccia utente.

So che posso utilizzare il dispatcher del thread dell'interfaccia utente, ma non sono sicuro di dove (il modello di visualizzazione potrebbe essere il posto giusto?), quindi mi piacerebbe sapere se segui qualche schema di progettazione per affrontare questa situazione.

    
posta mariosangiorgio 03.08.2014 - 14:37
fonte

2 risposte

1

Per scenari come questo, dovresti utilizzare BackgroundWorker o Attività .

Esempio di codice per l'utilizzo di BackgroundWorker:

var bw = new BackgroundWorker();
bw.DoWork += LongRunningBackgroundWork;
bw.RunWorkerCompleted += LongRunningBackgroundWorkCompleted;
bw.RunWorkerAsync();

void LongRunningBackgroundWork(object sender, DoWorkEventArgs e)
{
    // Perform long running task/work
    // Stuff e.Result with results
}

// this runs on the thread that kicked off BackgroundWorker
void LongRunningBackgroundWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Access results from e.Result
    // Any exceptions from e.Error
    // Update ViewModel and inturn UI with the results
}

Fai riferimento a questo MSDN How-to per step- esempio dettagliato sull'utilizzo di BackgroundWorker.

Codice di esempio per l'utilizzo delle attività:

var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Run(() =>
{
    // Long running Background work
    // return Results
}).ContinueWith(task =>
{
    // access results from "task.Result"
    // any errors from task.Exception and task.Exception.InnerExceptions
    // Update ViewModel inturn UI with the results
}, uiScheduler); // Pass the UI Scheduler, so that this task runs on UI thread!

E fare riferimento a questo MSDN How-to per il passaggio passo dopo passo sulla pianificazione del lavoro sul thread dell'interfaccia utente.

    
risposta data 26.08.2014 - 16:38
fonte
2

In WinForms, ho usato InvokeIfRequired per risolvere questo problema. Non ho lavorato molto con WPF, ma questo ragazzo scrive sull'equivalente WPF di InvokeIfRequired: link

Non molto di una risposta, ma meglio di niente, spero:)

    
risposta data 03.08.2014 - 18:25
fonte

Leggi altre domande sui tag