2010-07-14 8 views
8

¿Existe alguna manera de probar la unidad WaitHandle.WaitAll() al usar la solución de prueba integrada de Visual Studio? Cuando intento y ejecutar una prueba que utiliza esta función dentro de Visual Studio no pasa la prueba y al examinar los resultados de la prueba se muestra el siguiente error:¿Cómo uso WaitHandler.WaitAll en MSTest sin advertencias de STA?

WaitAll for multiple handles on a STA thread is not supported 

Me gustaría ser capaz de unidad de prueba el uso de WaitAll() ya que una cantidad creciente de la base de código de mi API ahora se está moviendo a un patrón IAsyncResult en comparación con otros medios de hacer operaciones de subprocesos múltiples.

Editar

Sobre la base de la sugerencia de Anthony aquí es un método de ayuda sencilla que se puede utilizar para invocar dicho código en un entorno de prueba de unidad:

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

¿Qué versión de Visual studio? –

+0

Visual Studio 2008 con la opción de pasar a 2010 si es necesario – RobV

Respuesta

7

Es posible que tenga dos problemas. El primero es el que usted indicó: No puede esperar en múltiples Manejadores de Espera in an STA thread (el estado del apartamento con rosca MSTest). Podemos arreglar eso con un hilo MTA creado manualmente.

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

El medio ambiente también tiene un maximum wait handle limit. En .NET 2.0, parece estar codificado en 64. Esperar más allá del límite producirá un NotSupportedException. Puede usar un método extension para esperar en todos los identificadores de espera en fragmentos.

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

y que le plataforma juntos como este en su prueba (en la Ley o hacer valer parte de la prueba)

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

Donde 'action' es la prueba de la unidad? –

+0

En este caso, la 'acción 'estaría esperando en todos los controladores. Actualizaré mi respuesta para mostrar un ejemplo de prueba unitaria y cómo encaja todo esto. –

+0

¿Entonces requiere cambios en el código productivo? ¿No se puede arreglar solo en la prueba unitaria? –

2

En Visual Studio 2008 & 2010 puede cambiar su archivo .testsettings para ejecutar las pruebas bajo un subproceso MTA agregando <ExecutionThread apartmentState="MTA" />.

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

Para mi Visual Studio 2010 solo funcionan las siguientes pruebas de configuración de configuración.

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

Para VS2008 las instrucciones son ligeramente diferentes en comparación con VS2010. Para VS2008, edite el archivo testrunconfig y agregue lo siguiente al elemento TestRunConfiguration:

<ExecutionThread apartmentState="MTA" /> 
Cuestiones relacionadas