2013-02-19 7 views
5

Sto cercando la procedura migliore per comunicare in modo asincrono tra i livelli. Sto utilizzando la mvvm light toolkitche cosa è asincrono in MVVM? Il modello o ViewModel. Miglior pratica?

Attualmente io uso un BackgroundWorker nel modelloperché ho visto questo nel codice generato automaticamente. Non con il backgroundworker ma con la chiamata asincrona.

public void GetConfig(Action<Config, Exception> callback) 
{ 
    BackgroundWorker backgroundWorker = new BackgroundWorker(); 
    backgroundWorker.DoWork += (backgroundWorkerSender, backgroundWorkerArgs) => 
    { 
     try 
     { 
      backgroundWorkerArgs.Result = AppEnvironment.Instance.Config; 
     } 
     catch (Exception exception) 
     { 
      backgroundWorkerArgs.Result = null; 
     } 
    }; 

    backgroundWorker.RunWorkerCompleted += (backgroundWorkerSender, backgroundWorkerArgs) => 
    { 
     if (backgroundWorkerArgs.Result != null) 
     { 
      callback((Config) backgroundWorkerArgs.Result, null); 
     } 
     else 
     { 
      /* ToDo: exceptionhandling */ 
     } 
    }; 

    backgroundWorker.RunWorkerAsync(); 
} 

Ora ho trovato la AsyncDelegateCommand che implementa la parte asincrona nel ViewModel.

private ICommand _refreshObjectDefinitionCommand; 
public ICommand RefreshObjectDefinitionCommand 
{ 
    get 
    { 
     return _refreshObjectDefinitionCommand 
      ?? (_refreshObjectDefinitionCommand = new AsyncDelegateCommand(delegate 
       { 
        IsBusy = true; 
        _dataService.GetObjectDefinition(
        (xmlObjectDef, errorConfig) => 
        { 
         if (errorConfig != null) 
         { 
          /* ToDo Lenz: exceptionhandling */ 
          return; 
         } 

         ObjectDefinition = xmlObjectDef; 
        }); 

        _dataService.GetObjectDefinitionTreeView(
         (treenodes, errorConfig) => 
         { 
          if (errorConfig != null) 
          { 
           /* ToDo Lenz: exceptionhandling */ 
           return; 
          } 

          TreeNodes = treenodes; 
         }); 
       }, 
           () => _isConnected, o => IsBusy = false, exception => IsBusy = false)); 
    } 
} 

Sono un po 'confuso riguardo alle migliori pratiche? Ho letto molti articoli Ma in qualche modo sono sempre opinioni diverse. C'è qualche misura per la migliore compatibilità con il normale sforzo di manutenzione?

alcuni spunti di riflessione

Modello:

http://csharperimage.jeremylikness.com/2009/12/simplifying-asynchronous-calls-in.html

http://www.dzone.com/articles/mvvmlight-and-async

ViewModel

http://www.codeproject.com/Articles/123183/Asynchronus-MVVM-Stop-the-Dreaded-Dead-GUI-Problem

http://www.codeproject.com/Articles/441752/Async-MVVM-Modern-UI

+0

Non sarebbe più facile leggere la sequenza di attività? Con asincrono/attendo .. – JustAnotherUserYouMayKnow

+0

ovviamente, ma per quanto ne so è solo da. Net 4.5 disponibile?!? –

+0

C'è un pacchetto NuGet per supportarlo per 4.0 e silverlight 5. Installalo nel tuo progetto e funziona come un incantesimo! http://nuget.org/packages/Microsoft.CompilerServices.AsyncTargetingPack/ – JustAnotherUserYouMayKnow

risposta

1

Beh, direi che la fecthing modello e trasformandola in vista modello è asincrona. Chi lo fa, dipende dall'architettura, può essere fatto sul modello di vista stesso o può utilizzare il livello controller per tali carichi asincroni e la mappatura della VM inizializzata da visualizzare. Anche i backgroundworker sono il passato che dovresti usare la classe Task per le operazioni parallele. E, naturalmente, non dimenticare di invocare tramite il dispatcher quando notifica la vista sulle modifiche da VM.

codice di esempio:

Task<string>.Factory.StartNew(() => 
{ 
    string text = GetArticleText(); 
    Application.Current.Dispatcher.BeginInvoke(new Action(()=>MyTextProperty = text)); 
}); 
1

vorrei suggerire di mettere il codice asincrono nel vostro ViewModel e lasciare il vostro modello per memorizzare i dati. Quando stavo iniziando su MVVM, una delle prime cose che ho imparato è stato rimuovere la logica dai miei modelli e invece tenerla nei miei ViewModels. Anche se direi che dove metti il ​​tuo codice non importa finché tutte le persone che leggono il codice possono capirlo.

Problemi correlati