2010-07-14 5 views
8

C'è un modo per testare l'unità WaitHandle.WaitAll() quando si utilizza la soluzione di test dell'unità integrata di Visual Studio. Quando provo ed eseguire un test che utilizza questa funzione all'interno di Visual Studio il test fallisce e quando l'esame dei risultati del test viene visualizzato il seguente errore:Come utilizzare WaitHandler.WaitAll in MSTest senza avvisi STA?

WaitAll for multiple handles on a STA thread is not supported 

mi piacerebbe essere in grado di unit test l'uso di WaitAll() poiché una quantità crescente della base di codice della mia API si sta ora spostando su un modello IAsyncResult anziché su altri mezzi per eseguire operazioni multi-thread.

Modifica

Basato su suggerimento di Anthony ecco un metodo di supporto semplice che può essere utilizzato per richiamare tale codice in un ambiente di test di unità:

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

Quale versione di Visual Studio? –

+0

Visual Studio 2008 con possibilità di passare al 2010 se necessario – RobV

risposta

7

Si possono avere due problemi. Il primo è quello che hai dichiarato: Non puoi aspettare su più Wait Handle in an STA thread (lo stato dell'appartamento thread MSTest). Possiamo aggiustarlo con un thread MTA creato manualmente.

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

L'ambiente ha anche un maximum wait handle limit. In .NET 2.0, sembra essere codificato a 64. Attendere oltre il limite produrrà un NotSupportedException. È possibile utilizzare un metodo extension per attendere su tutti gli handle di attesa in blocchi.

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

e desideri rig insieme come questo nel tuo test (nella legge o Assert parte del test)

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

Dove 'action' è il test unitario? –

+0

In questo caso, l'azione 'sarebbe in attesa su tutti gli handle. Aggiornerò la mia risposta per mostrare un test unitario di esempio e in che modo tutto ciò si adatta. –

+0

Quindi richiede modifiche nel codice produttivo? Non può essere riparato solo nel test dell'unità? –

2

In Visual Studio 2008 & 2010 è possibile modificare il file .testsettings per eseguire i test sotto un thread MTA aggiungendo <ExecutionThread apartmentState="MTA" />.

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

Per il mio Visual Studio 2010 solo la seguente configurazione ha eseguito test.

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

Per VS2008 le istruzioni sono leggermente diverse rispetto a VS2010. Per VS2008, modificare il file testrunconfig e aggiungere quanto segue all'elemento TestRunConfiguration:

<ExecutionThread apartmentState="MTA" /> 
Problemi correlati