2008-11-06 16 views
6

Tengo una aplicación con la siguiente arquitectura básica:Cómo depurar llamadas remotas .NET?

Un servicio de Windows (Servicio) que registra un tipo .NET (RemoteObject) para acceso remoto (.NET Remoting). RemoteObject crea subprocesos no ThreadPool que usan ThreadPool para hacer el procesamiento IO. El tamaño del ThreadPool debe estar restringido a un límite por un motivo en particular. Una aplicación GUI usa .NET Remoting para acceder a RemoteObject.

Me di cuenta de que si el tamaño del ThreadPool es demasiado bajo, la aplicación GUI se bloqueará al realizar una llamada a RemoteObject.

Mi pregunta es, ¿cómo puedo averiguar por qué está colgando, y por qué el subproceso RemoteObject se verá afectado por ThreadPool?

Esto me está volviendo loco; ¡Gracias por tu ayuda!

+0

Bueno, dices "RemoteObject crea subprocesos no ThreadPool que usan ThreadPool para hacer el procesamiento IO". ¿No puede ser esta la razón (es decir, los hilos que no son ThreadPool están esperando a que se abran las ranuras de ThreadPool)? – Alan

+0

¿Por qué eso afectaría el hilo en el que está RemoteObject? La GUI no puede acceder al método RemoteObject al que está llamando. – Chris

+0

Si es posible cambiar esto, remójense para WCF. – Will

Respuesta

4

Resulta que la infraestructura remota de .NET utiliza .NET ThreadPool (o comparte el recurso subyacente), por lo que las llamadas remotas pueden bloquearse si su aplicación utiliza todos los subprocesos de ThreadPool.

2

Esto puede no ser excepcionalmente útil, pero lo arrojaré de todos modos.

Al depurar servicios y clientes que hablan a través de la comunicación remota, generalmente siempre ejecutaré dos instancias del depurador: una para el cliente y otra para el servicio. Solo para ser claro, estoy ejecutando dos copias de Visual Studio. Para el servicio puede usar el comando adjuntar o puede alterar el inicio y el inicio de la llamada directamente (evitando todo el código de servicio).

Así es como normalmente habilito la depuración alterando la llamada principal, debe hacerlo y la llamada al servicio DebugService, realmente es solo un punto de entrada que llama a inicio. Una vez que tengo esto, simplemente habilito la depuración del servicio por el SERVICE_DEBUG definitivo o cambiando el #if agregando un '!'. Ahora básicamente has convertido tu servicio a una aplicación de consola.

#if SERVICE_DEBUG 
      ServiceHost s = new ServiceHost(); 
      s.DebugService(); 
      Thread.Sleep(300000000); 

#else 
      ServiceBase.Run(ServicesToRun); 
#endif 

Una vez que tenga tanto la configuración y funcionamiento se puede pasar por el cliente, cuando las llamadas de comunicación remota golpean el servicio que se puede recorrer el código de servicio, lo que le permite depurar las dos al mismo tiempo.

Por curiosidad ¿está llamando al objeto remoto directamente desde el hilo de la GUI? Si es así, el hilo de la GUI se bloqueará hasta que se complete la llamada remota. Esto bloqueará toda la GUI y la dejará sin respuesta. Esta no es la solución al problema, pero si ese es el caso y su cadena de servicio no está volviendo, la GUI se bloqueará también.

+0

! no es realmente bueno, ya que lo alternará, mejor prefijarlo con una 'n'. – leppie

4

No estoy seguro de si esto ayuda (no puedo decir si esto es su problema o no), pero si desea depurar su servicio como su funcionamiento, puede dar una palmada esto en su código:

#if DEBUG 
      if (!System.Diagnostics.Debugger.IsAttached) 
       Debugger.Launch(); 
#endif 

y obtendrá un cuadro de diálogo que le pedirá que seleccione un depurador. Es una forma fácil de adjuntar a una instancia en ejecución de un servicio. Si nada más, esto le permitirá acceder a su servicio cuando la interfaz de usuario esté colgando (presionando el botón de pausa en su barra de herramientas de depuración) y revise sus hilos y la pila de llamadas.

+0

No tengo el problema de los solicitantes, pero esta solución me ayudó muchísimo. :) – rythos42

1

Hace algunos años, diseñé e implementé un sistema empresarial crítico que utilizaba .NET Remoting. Tuvimos un cliente implementado como una GUI de Windows Forms, un servidor implementado como un servicio de Windows y una base de datos de SQL Server.

Diseñé para la resolución de problemas/depuración/desarrollo, por lo que uno de mis primeros criterios de diseño fue que podía eliminar trivialmente toda la implementación de .NET Remoting y ejecutar todo el sistema en mi escritorio. Entonces, podría desactivar la comunicación remota cambiando una configuración de configuración booleana a "falso" = apagado.Luego podría solucionar problemas, depurar, desarrollar completamente sin la sobrecarga o la interferencia de .NET Remoting.

Parece que esto sería valioso para su situación también. Como cuestión de hecho, no puedo imaginar una situación en la que esa no sea una característica deseable, especialmente porque es fácil de implementar.

Por lo tanto, para implementarlo, cada uno de los clientes y el código del servidor usaban la configuración para decidir qué clase de implementación instanciar para la comunicación con el otro lado. Toda la comunicación se realizó a través de una interfaz personalizada C# que tenía dos clases concretas de implementación en cada lado: una clase implementó la comunicación usando .NET Remoting, la otra clase implementó la comunicación como un paso directo en el proceso (llamadas directas).

Solo un par de clases (una en cada lado) sabían algo acerca de .NET Remoting, por lo que el aislamiento fue total. La mayoría de las veces, todos los desarrolladores trabajaron con la comunicación remota desactivada, que era más rápida y sencilla. Cuando lo necesitaban, en raras ocasiones, lo activaban (la mayoría de las veces solo yo, o cuando alguien se conectaba a prueba/producción para solucionar problemas).

Por cierto, hice la interfaz de interacción remota muerto simple: respuesta pública ejecutar (Solicitud)

Más allá de eso, también se utiliza el depurador lanzamiento de punta se mencionó anteriormente, y estoy de acuerdo que es necesario tener en cuenta el impacto en el enhebrado de GUI.

Cuestiones relacionadas