2010-04-29 11 views
2

J'utilise NUnit pour tester View Models dans une application WPF 3.5 et j'utilise la classe BackgroundWorker pour exécuter des commandes asynchrones. Les tests unitaires fonctionnent correctement avec le runner NUnit ou le runner ReSharper mais échoue sur le serveur TeamCity 5.1.BackgroundWorker ne fonctionne pas avec le runner TeamCity NUnit

Comment est-il mis en œuvre:

J'utilise une propriété nommée ViewModelIsBusy et le mettre à faux sur l'événement BackgroundWorker.RunWorkerCompleted. Dans mon test j'utilise cette méthode pour attendre le BackgroundWorker pour terminer:

protected void WaitForBackgroundOperation(ViewModel viewModel) 
{ 
    Console.WriteLine("WaitForBackgroundOperation 1"); 
    int count = 0; 
    while (viewModel.IsBusy) 
    { 
     Console.WriteLine("WaitForBackgroundOperation 2"); 
     RunBackgroundWorker(); 
     Console.WriteLine("WaitForBackgroundOperation 3"); 

     if (count++ >= 100) 
     { 
      Assert.Fail("Background operation too long"); 
     } 
     Thread.Sleep(1000); 

     Console.WriteLine("WaitForBackgroundOperation 4"); 
    } 
} 

private static void RunBackgroundWorker() 
{ 
    Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })); 
    System.Windows.Forms.Application.DoEvents(); 
} 

Eh bien, parfois ça marche et parfois il se bloque la construction. Je suppose que c'est le Application.DoEvents() mais je ne sais pas pourquoi ...

Edit: J'ai ajouté quelques traces (voir code ci-dessus) et dans le journal que j'ai:

WaitForBackgroundOperation 1 
WaitForBackgroundOperation 2 
WaitForBackgroundOperation 2 
WaitForBackgroundOperation 2 
... 

Comment est-il possible ?!

Répondre

0

Vous lancez un tas de tâches d'arrière-plan, une par seconde. Déplacez RunBackgroundWorker au-dessus de la boucle.

protected void WaitForBackgroundOperation(ViewModel viewModel) 
{ 
    Console.WriteLine("WaitForBackgroundOperation 1"); 
    RunBackgroundWorker(); 
    Thread.Sleep(100); // wait for thread to set isBusy, may not be needed 
    int count = 0; 
    while (viewModel.IsBusy) 
    { 
     Console.WriteLine("WaitForBackgroundOperation 2"); 
     if (count++ >= 100) 
     { 
      Assert.Fail("Background operation too long"); 
     } 
     Thread.Sleep(1000); 
     Console.WriteLine("WaitForBackgroundOperation 3"); 
    } 
} 

private static void RunBackgroundWorker() 
{ 
    Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })); 
} 

Les DoEvents ne devraient pas être nécessaires.