Question

Existe-t-il un moyen de tester unitairement WaitHandle.WaitAll() lors de l'utilisation de la solution de tests unitaires intégrée de Visual Studio.Lorsque j'essaie d'exécuter un test qui utilise cette fonction dans Visual Studio, le test échoue et lors de l'examen des résultats du test, l'erreur suivante s'affiche :

WaitAll for multiple handles on a STA thread is not supported

J'aimerais pouvoir tester unitairement l'utilisation de WaitAll() puisqu'une quantité croissante de la base de code de mon API est désormais migrée vers un IAsyncResult modèle par opposition à d’autres moyens d’effectuer des opérations multithread.

Modifier

Basée sur la suggestion d'Anthony, voici une méthode d'assistance simple qui peut être utilisée pour appeler 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();
}
Était-ce utile?

La solution

Vous pouvez avoir deux problèmes.Le premier est celui que vous avez indiqué :Vous ne pouvez pas attendre sur plusieurs poignées d'attente dans un fil de discussion STA (l'état cloisonné du thread MSTest).Nous pouvons résoudre ce problème avec un thread MTA créé manuellement.

public static void OnMtaThread(Action action)
{
    var thread = new Thread(new ThreadStart(action));
    thread.SetApartmentState(ApartmentState.MTA);
    thread.Start();
    thread.Join();
}

L'environnement a également un limite maximale de traitement d'attente.Dans .NET 2.0, il semble être codé en dur à 64.Attendre plus que la limite produira un NotSupportedException.Vous pouvez utiliser un extension méthode pour attendre toutes les poignées d'attente en morceaux.

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 les assembleriez comme ceci dans votre test (dans la partie Act ou Assert du test)

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

Autres conseils

Dans Visual Studio 2008 et 2010 tu peux changer ton .testsettings fichier pour exécuter les tests sous un thread MTA en ajoutant <ExecutionThread apartmentState="MTA" />.

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

Pour mon Visual Studio 2010, seule la configuration suivante a fait fonctionner les tests.

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

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

<ExecutionThread apartmentState="MTA" />
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top