2010-07-14 6 views
8

Gibt es eine Möglichkeit zum Komponententest WaitHandle.WaitAll(), wenn die in Visual Studio integrierte Komponententestlösung verwendet wird. Wenn ich versuche, und einen Test durchführen, die diese Funktion in Visual Studio verwendet der Test fehlschlägt und wenn die Testergebnisse der folgende Fehler angezeigt wird, untersucht:Wie verwende ich WaitHandler.WaitAll in MSTest ohne STA-Warnungen?

WaitAll for multiple handles on a STA thread is not supported 

würde Ich mag die Verwendung von WaitAll() zu Unit-Test in der Lage sein da ein zunehmender Teil der Codebasis meiner API sich nun auf ein IAsyncResult Muster verschiebt, im Gegensatz zu anderen Mitteln zur Durchführung von Multithread-Operationen.

bearbeiten

auf Anthony Vorschlag Basierend hier ist eine einfache Hilfsmethode, die verwendet werden können, einen solchen Code in einer Einheit Testumgebung aufzurufen:

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

Welche Version von Visual Studio? –

+0

Visual Studio 2008 mit der Möglichkeit, bei Bedarf auf 2010 umzusteigen – RobV

Antwort

7

Sie haben zwei Probleme. Der erste ist der, den Sie angegeben haben: Sie können nicht auf mehrere Warte-Handles in an STA thread warten (der MSTest-Thread-Apartment-Status). Wir können das mit einem manuell erstellten MTA-Thread beheben.

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

Die Umgebung hat auch eine maximum wait handle limit. In .NET 2.0 scheint es auf 64 fest codiert zu sein. Warten auf mehr als das Limit wird NotSupportedException produzieren. Sie können eine extension-Methode verwenden, um auf alle Warte-Handle in Chunks zu warten.

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; 
    } 
} 

und Sie würden rig sie wie folgt zusammen in Ihrem Test (im Gesetz oder einen Teil des Test Behaupten)

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

Wo ist "Aktion" der Komponententest? –

+0

In diesem Fall würde die "Aktion" auf allen Handles warten. Ich werde meine Antwort aktualisieren, um einen Beispiel-Komponententest zu zeigen und wie das alles zusammenpasst. –

+0

Also erfordert es Änderungen im produktiven Code? Kann nur im Komponententest nicht behoben werden? –

2

In Visual Studio 2008 & 2010 können Sie Ihre .testsettings Datei ändern, um die Tests zu laufen unter ein MTA-Thread, indem <ExecutionThread apartmentState="MTA" /> hinzugefügt wird.

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

Für meine Visual Studio 2010 hat nur die folgende Konfiguration Tests durchgeführt.

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

Für VS2008 sind die Anweisungen etwas anders als VS2010. Bearbeiten Sie für VS2008 die Datei testrunconfig, und fügen Sie dem Element TestRunConfiguration Folgendes hinzu:

<ExecutionThread apartmentState="MTA" /> 
Verwandte Themen