c# signalr using

c# - Explique por qué “usar” no funciona en el servicio?



signalr using (2)

¿Qué está mal con tu servicio?

El problema que tiene es que su Console.ReadLine realiza una espera de bloqueo para la entrada estándar. Eso se bloqueará para siempre en un servicio de Windows y hará que el administrador de control de servicios agote el tiempo de inicio del servicio después de 30 segundos. Esta pregunta tiene más información sobre lo que está pasando.

Si elimina todo el contenido de la declaración de uso, y la declaración en sí misma como lo hizo con el servidor que inició WebApp.Start continuará en segundo plano una vez que se complete el método de Start servicio. Este es el comportamiento correcto de un servicio.

Lo que efectivamente está haciendo aquí es filtrar los trabajadores asíncronos que creó WebApp.Start . Esto significa que todavía se están ejecutando después de que se complete el inicio del servicio para escuchar las solicitudes.

Probablemente debería hacer un seguimiento del IDisposable que WebApp.Start devolver WebApp.Start , y eliminarlo en el método Stop .

¿Qué pasa con el using ?

Una declaración de using se asegura de que un recurso esté siempre dispuesto cuando el control abandona el bloque de la declaración de using . Esto puede deberse a que se haya lanzado una excepción o porque el bloque se complete con éxito y el control pase a la siguiente parte del programa.

using declaraciones de using se utilizan cuando se sabe que nada quiere acceder al recurso una vez que se ha completado el bloqueo. Este suele ser el caso cuando se trata de métodos que le devuelven un IDisposable . Sin embargo, en su caso, no desea llamar a desechar porque desea que los subprocesos que WebApp.Start creó continúen después de que se inicie el servicio.

Así que estuve atrapado en este problema durante aproximadamente una semana. Estaba intentando ejecutar un proyecto para recibir una conexión TCP e iniciar un concentrador SignalR como servicio. Ambos funcionaron perfectamente ejecutando el proyecto como un archivo .exe . La parte TCP funcionaría perfectamente, sin embargo, estaba teniendo problemas con el lado SignalR.

La razón terminó siendo la declaración de uso .

antes de

using (WebApp.Start<SignalrStartup>(url)) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Server running on {0}", url); // was url Console.WriteLine("ID/tMessage"); Console.ReadLine(); }

Después

WebApp.Start<SignalrStartup>(url);

Intenté ejecutar el código con Console.WriteLine() comentó, ya que pensé que podría estar lanzando una excepción, ya que no hay ninguna consola que se pueda ejecutar como servicio una vez. Esto tampoco funcionó, pero tampoco funcionaría como un archivo .exe , ya que necesitaba la Console.ReadLine() para mantener la consola abierta, de alguna manera como la necesita para mantener abierto HelloWorld.cs . Una vez que se eliminó el contenedor de uso junto con la consola , funcionaría tanto en el archivo .exe como en el servicio.

He leído que la instrucción using mata los objetos que contiene una vez que abandonas el contenedor. Pero no entiendo cómo el bit Después de código mantiene abierto el código .exe una vez que se ejecuta. ¿Hay algún punto en usar o lo he usado mal?

Editar

protected override void OnStart(string[] args) { Task.Factory .StartNew(() => StartTCP()) .ContinueWith(t => StartSignalR()); }

La llamada se realiza desde el método StartSignalR() .


Webapp.Start <> inicia subprocesos de trabajo. Estos hilos mantienen en ejecución su archivo ejecutable, incluso después de que el código en su HelloWorld.cs haya terminado de ejecutarse. Su exe no se apagará hasta que todos los subprocesos de trabajo se hayan detenido.

Cuando agregue su declaración "utilizando", el marco llamará a Dispose en su aplicación SignalR. Esta llamada detendrá todos los subprocesos de trabajo, y su exe terminará.

La instrucción Readline () impide que la aplicación llegue al final de la instrucción using. Esto significa que el método de desechar no se llama hasta que presione Entrar.

Por lo tanto, para un exe, normalmente desea utilizar ReadLine de la forma en que lo hace. Para un servicio que desea almacenar una referencia a su IDisposable, y llamar a disponer en él en su método Stop ().