Frage

Gibt es eine Möglichkeit zum Komponententest WaitHandle.WaitAll() bei Verwendung der integrierten Komponententestlösung von Visual Studio.Wenn ich versuche, einen Test auszuführen, der diese Funktion in Visual Studio verwendet, schlägt der Test fehl und bei der Überprüfung der Testergebnisse wird der folgende Fehler angezeigt:

WaitAll for multiple handles on a STA thread is not supported

Ich würde gerne in der Lage sein, die Verwendung von zu testen WaitAll() da ein zunehmender Teil der Codebasis meiner API jetzt auf eine verschoben wird IAsyncResult muster im Gegensatz zu anderen Methoden zum Ausführen von Multithread-Operationen.

Bearbeiten

Basierend auf Anthonys Vorschlag ist hier eine einfache Hilfsmethode, mit der solcher Code in einer Komponententestumgebung aufgerufen werden kann:

public static void TestInMTAThread(ThreadStart info)
{
    Thread t = new Thread(info);
    t.SetApartmentState(ApartmentState.MTA);
    t.Start();
    t.Join();
}
War es hilfreich?

Lösung

Sie können zwei Probleme haben.Der erste ist der, den Sie angegeben haben:Sie können nicht auf mehrere Wartegriffe warten in einem STA-Thread (der Status der MSTest-Thread-Wohnung).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 Umwelt hat auch eine maximales Limit für Wartehandles.In .NET 2.0 scheint es fest auf 64 codiert zu sein.Das Warten auf mehr als das Limit führt zu einer NotSupportedException.Sie können eine verwenden Erweiterung methode zum Warten auf alle Wartehandles in Blöcken.

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 du würdest sie in deinem Test so zusammenbauen (im Akt oder im Assert-Teil des Tests)

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

Andere Tipps

In Visual Studio 2008 und 2010 sie können Ihre ändern .testsettings datei zum Ausführen der Tests unter einem MTA-Thread durch Hinzufügen <ExecutionThread apartmentState="MTA" />.

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

Für mein Visual Studio 2010 hat nur die folgende Konfiguration Tests zum Laufen gebracht.

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

Für VS2008 unterscheiden sich die Anweisungen geringfügig von VS2010.Bearbeiten Sie für VS2008 die testrunconfig-Datei und fügen Sie dem TestRunConfiguration-Element Folgendes hinzu:

<ExecutionThread apartmentState="MTA" />
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top