2010-07-14 22 views
8

Existe-t-il un moyen d'effectuer le test unitaire WaitHandle.WaitAll() lors de l'utilisation de la solution de test unitaire intégrée de Visual Studio. Lorsque je tente et exécuter un test qui utilise cette fonction dans Visual Studio le test échoue et lors de l'examen des résultats des tests l'erreur suivante est affichée:Comment utiliser WaitHandler.WaitAll dans MSTest sans avertissements STA?

WaitAll for multiple handles on a STA thread is not supported 

Je voudrais être en mesure de test unitaire l'utilisation de WaitAll() Puisqu'une quantité croissante de la base de code de mon API est maintenant passer à un modèle IAsyncResult par opposition à d'autres moyens de faire des opérations multi-thread.

Modifier

Basé sur la suggestion d'Anthony est une méthode simple d'aide ici qui peut être utilisé pour invoquer un tel code dans un environnement de test unitaire:

public static void TestInMTAThread(ThreadStart info) 
{ 
    Thread t = new Thread(info); 
    t.SetApartmentState(ApartmentState.MTA); 
    t.Start(); 
    t.Join(); 
} 
+0

Quelle version de Visual Studio? –

+0

Visual Studio 2008 avec possibilité de passer à 2010 si nécessaire – RobV

Répondre

7

Vous pouvez avoir deux problèmes. Le premier est celui que vous avez déclaré: Vous ne pouvez pas attendre sur plusieurs poignées d'attente in an STA thread (l'état de l'appartement du thread MSTest). Nous pouvons résoudre cela avec un thread MTA créé manuellement. L'environnement a également . Dans .NET 2.0, il semble être dur codé à 64. Attente sur plus que la limite produira un NotSupportedException. Vous pouvez utiliser une méthode extension pour attendre toutes les poignées d'attente en blocs.

public static void WaitAll<T>(this List<T> list, TimeSpan timeout) 
    where T : WaitHandle 
{ 
    var position = 0; 
    while (position <= list.Count) 
    { 
     var chunk = list.Skip(position).Take(MaxWaitHandles); 
     WaitHandle.WaitAll(chunk.ToArray(), timeout); 
     position += MaxWaitHandles; 
    } 
} 

Et vous rig les ensemble comme dans votre test (dans la Loi ou VALOIR partie du test)

OnMtaThread(() => handles.WaitAll(Timespan.FromSeconds(10))); 
+0

Où 'action' est le test unitaire? –

+0

Dans ce cas, l'action 'attendrait sur toutes les poignées. Je mettrai à jour ma réponse pour montrer un exemple de test unitaire et comment tout cela s'accorde. –

+0

Donc, cela nécessite des changements dans le code de production? Il ne peut pas être fixé dans le test unitaire seulement? –

2

En Visual Studio 2008 & 2010 vous pouvez modifier votre fichier .testsettings pour exécuter les tests sous un thread MTA en ajoutant <ExecutionThread apartmentState="MTA" />.

<Execution> 
    <ExecutionThread apartmentState="MTA" /> 
</Execution> 
0

Pour mon Visual Studio 2010, seule la configuration suivante a permis aux tests de fonctionner.

<Execution> 
    <ExecutionThread apartmentState="1" /> 
</Execution> 
0

Pour VS2008, les instructions sont légèrement différentes par rapport à VS2010. Pour VS2008, modifiez le fichier testrunconfig et ajoutez ce qui suit à l'élément TestRunConfiguration:

<ExecutionThread apartmentState="MTA" />