2012-12-20 2 views
1

J'ai une petite application MVVM qui communique avec une base de données. Quel (le cas échéant) est le moyen standard pour effectuer des transactions de base de données dans un thread d'arrière-plan qui met à jour l'interface utilisateur lorsque vous avez terminé? Dois-je utiliser BackgroundWorkers, TPL ou implémenter mes propres threads? Actuellement, j'ai une classe statique avec la méthode suivante pour le travail d'arrière-plan:Tâches, BackgroundWorkers ou nouveaux threads pour les transactions de base de données dans WPVM MVVM?

public static void RunAsync(Action backgroundWork, Action uiWork, Action<Exception> exceptionWork) { 

    var uiContext = TaskScheduler.FromCurrentSynchronizationContext(); 

    // The time consuming work is run on a background thread. 
    var backgroundTask = new Task(() => backgroundWork()); 

    // The UI work is run on the UI thread. 
    var uiTask = backgroundTask.ContinueWith(_ => { uiWork(); }, 
     CancellationToken.None, 
     TaskContinuationOptions.OnlyOnRanToCompletion, 
     uiContext); 

    // Exceptions in the background task are handled on the UI thread. 
    var exceptionTask = backgroundTask.ContinueWith(t => { exceptionWork(t.Exception); }, 
     CancellationToken.None, 
     TaskContinuationOptions.OnlyOnFaulted, 
     uiContext); 

    // Exceptions in the UI task are handled on on the UI thread. 
    var uiExceptionTask = uiTask.ContinueWith(t => { exceptionWork(t.Exception); }, 
     CancellationToken.None, 
     TaskContinuationOptions.OnlyOnFaulted, 
     uiContext); 

    backgroundTask.Start(); 
} 

Répondre

3

Vous pouvez utiliser async/await, qui vous donnera une syntaxe plus naturelle:

public static async Task RunAsync(Action backgroundWork, Action uiWork, Action<Exception> exceptionWork) 
{ 
    try 
    { 
    // The time consuming work is run on a background thread. 
    await Task.Run(backgroundWork); 

    // The UI work is run on the UI thread. 
    uiWork(); 
    } 
    catch (Exception ex) 
    { 
    // Exceptions in the background task and UI work are handled on the UI thread. 
    exceptionWork(ex); 
    } 
} 

Ou mieux encore, il suffit de remplacer RunAsync avec le code lui-même, donc au lieu de

T[] values; 
RunAsync(() => { values = GetDbValues(); },() => UpdateUi(values), ex => UpdateUi(ex)); 

Vous pouvez dire:

try 
{ 
    var values = await Task.Run(() => GetDbValues()); 
    UpdateUi(values); 
} 
catch (Exception ex) 
{ 
    UpdateUi(ex); 
} 
+0

Merci, c'est exactement ce que je cherchais! – Coder1095

0

Eh bien, vous pouvez utiliser l'une de ces techniques. Je les ferais toujours sur un fil séparé bien. L'important est que l'action du thread soit ramenée sur le thread de l'interface utilisateur au moment approprié. Ma préférence est d'utiliser une tâche ou async attendre si .net 4.5

+0

'await' a l'avantage de ne pas bloquer un thread en attendant l'opération asynchrone. – Servy

+0

En effet - bon point .. –

Questions connexes