Las acciones del controlador se activan varias veces: la aplicación ASP.NET MVC 4 se ejecuta en el emulador de Azure

Esto puede llevar un tiempo explicar, pero aquí voy :).

Creé dos proyectos de Visual Studio 2012:

Un proyecto que usa la plantilla (Web -> ASP.NET MVC 4 Web Application) en Visual StudioAñadir proyecto diálogo. No agregué un proyecto de prueba de unidad.Un proyecto que utiliza la plantilla de servicio en la nube de Azure (Cloud -> Windows Azure Cloud Service). Agregué un solo rol, un ASP.NET MVC 4 Web Role, y nuevamente no agregué un proyecto de prueba de unidad.

Dejé estos dos proyectos totalmente intactos por la forma en que Visual Studio los creó para mí.

porcada proyecto, luego fui a laHomeController clase y establecer un punto de interrupción en cada una de lasAbout yContact Métodos de acción (acciones aburridas que solo devuelven una vista). Por ejemplo, establezco un punto de interrupción en la única línea del método:

public ActionResult About()
{
     return View();
}

Entonces comencé a depurar el primer proyecto (el proyecto que no es Azure). Todo fue como se esperaba, es decir, cuando uso el navegador para navegar entre las páginas Acerca y Contacto, el punto de interrupción en los métodos de acción respectivos se vería afectado una vez en cada solicitud. Me pareció bien.

Entonces comencé a depurar el proyecto de Azure. Seguí el mismo procedimiento de navegación entre las páginas Acerca y Contacto. Esta vez encontré interesantes conductas no deterministas. En algunas solicitudes, el punto de interrupción en el método de acción se golpearía varias veces (a veces más de dos veces) antes de que la página se renderizara. A veces, la solicitud simplemente se bloquea y la página no se procesa (incluso después de minutos de espera).

Me gustaría saber por qué sucede esto, porque está afectando cosas más complicadas en otra aplicación de Azure MVC en la que estamos trabajando (por ejemplo, debido a este problema, la aplicación puede intentar crear dos o más instancias de un objeto modelo en mi base de datos para una solicitud).

Estoy en el siguiente entorno:

Windows 8 Pro (x64)Visual Studio 2012 UltimateWindows Azure SDK para Visual Studio 2012IIS 8 ExpressNavegador Firefox con Firebug (también confirmó el comportamiento usando IE)SQL Server 2012 (no es realmente relevante, supongo)

Lo único interesante que noté es que el siguiente mensaje de advertencia aparece en elSalida Ventana en Visual Studio cada vez que depuro el proyecto de Azure:

Reasignando los puertos privados 80 a 81 en el rol 'My_Web_Role_Name' para evitar conflictos durante la emulación.

Tal vez esta reasignación tenga algo que ver con eso. Entonces otra vez, después de hacer unanetstat -ano Vi que el proceso de Azure Development Fabric se está escuchando en el puerto 80, por lo que quizás sea por eso que tiene que hacer la reasignación ... suena bastante justo.

De todos modos, espero que alguien tenga una idea de lo que podría estar causando este comportamiento. Aquí hay algunos puntos y enfoques adicionales que probé:

Reinicie IIS, reinicie el emulador de cálculo / almacenamiento de Azure, reinicie toda la máquinaElimine las vistas de todas las secuencias de comandos (es decir, el comportamiento sigue existiendo si las páginas solo tienen un párrafo HTML básico en ellas)Intenté encontrar los archivos de registro relevantes de IIS Express, pero parece que los proyectos de Azure no se ejecutan a través de IIS Express como lo hace el otro proyecto (¿es correcto?).Supervisé la consola de Azure Compute Emulator ... nada muy interesante allí.

Así que ... finalmente, algunas preguntas:

¿Alguien más puede reproducir este comportamiento?¿Hay algún registro adicional generado por el Emulador de Azure que pueda ayudarme?

Realmente apreciaría un empujón en la dirección correcta aquí :).

¡Aclamaciones!

EDITAR

Aquí hay más información (estoy actualizando esta pregunta a medida que continúo depurando este problema):

Decidí ejecutar la solución sin depurar, y puse algunos mensajes de depuración simples en ambosAbout yContact Métodos de acción, por ejemplo:

public ActionResult About()
{
     System.IO.File.AppendAllText(@"c:\Logs\azure.log", DateTime.Now + ": Contact, thread " + System.Threading.Thread.CurrentThread.ManagedThreadId + "\r\n");
     return View();
}

Os adjuntoCola A este archivo y también se puso en marcha.Violinista para ver lo que estaba pasando a través de HTTP. Navegando entre los dosAbout yContact Enlaces de nuevo, vi la siguiente salida:

Desde la cola:

...12/12/2012 12:14:07 PM: Acerca de, hilo 712/09/2012 12:14:08 PM: Contacto, hilo 712/12/2012 12:14:09 PM: Acerca de, hilo 712/12/2012 12:14:10 PM: Contacto, hilo 712/09/2012 12:14:11 PM: Acerca de, hilo 612/09/2012 12:14:12 PM: Contacto, hilo 812/12/2012 12:14:31 PM: Contacto, hilo 712/09/2012 12:14:50 PM: Contacto, hilo 712/12/2012 12:15:03 PM: Acerca de, hilo 712/12/2012 12:15:05 PM: Contacto, hilo 812/12/2012 12:15:23 PM: Acerca de, hilo 612/12/2012 12:15:42 PM: Acerca de, hilo 1412/09/2012 12:16:01 PM: Acerca de, hilo 612/09/2012 12:16:31 PM: Contacto, hilo 712/09/2012 12:16:33 PM: Acerca de, hilo 14...12/12/2012 12:17:08 PM: Contacto, hilo 1212/12/2012 12:17:09 PM: Acerca de, hilo 1212/12/2012 12:17:28 PM: Acerca de, hilo 5...

De Fiddler para las mismas solicitudes (tenga en cuenta que también he estado jugando con la configuración de los puntos finales de mi rol, sin éxito):

Entonces ... los mensajes para llevar aquí son:

El tráfico HTTP parece normal (Fiddler no muestra ninguna solicitud duplicada)Los métodos de acción se llaman dos o tres veces para la misma solicitud, aparentemente no determinista (es decir, el problema original descrito anteriormente)Curiosamente, en mi situación, parece como siexactamente Los años 19 pasan antes de que ocurra otro 'golpe' en el método de acción (es decir, cuando los métodos de acción se golpean varias veces, la diferencia de tiempo entre los golpes es determinista)Las identificaciones de hilos generalmente son diferentes para cada hit siempre que los métodos de acción se golpean varias veces

Seguiré investigando más a fondo ... tal vez alguien tenga la amabilidad de ofrecer una sugerencia basada en esta información actualizada, aunque :).

Editar 2 Decidí imprimir la ID del proceso junto con la ID del hilo dentro del método de acción en cada caso. Para cada solicitud, la ID del proceso fue la correspondiente al Proceso del trabajador de IIS Express. Por lo tanto, parece que el proceso de trabajo de IIS Express a veces genera múltiples subprocesos para manejar la solicitud, cada uno de ellos con una diferencia de 19 años.

... y más profundo voy ... :)

EDITAR 3

Creo que me estoy acercando al problema ... Eché un vistazo a la bandeja de IIS Express y vi lo siguiente después de haber iniciado la aplicación (sin depurar):

Decidí usar esta URL directamente (en lugar de 127.0.0.2:8888 como se muestra en Fiddler arriba), y el problema pareció desaparecer. Ahora está empezando a tener sentido ... si invoco la aplicación IIS directamente sobre el puerto 8889, todo funciona bien como lo hizo con el proyecto original que no es de Azure. Si invoco el rol web (es decir, la parte específica de Azure) sobre el puerto 8888, a veces parece invocar la aplicación IIS varias veces.

Así que estoy empezando a reducir mi enfoque en el rol web ahora. Intentaré ver si puedo encontrar algunos registros de roles web relevantes ...

EDITAR 4

me asegurédiagnóstico fue configurado correctamente en la aplicación y lo ejecutó en modo de depuración. Luego fui a la interfaz de usuario de Azure Compute Emulator, hice clic con el botón derecho en mi instancia de rol web y seleccioné "Abrir tienda local". Esto me llevó a Explorer, donde pude encontrar una carpeta secundaria "temp \ temp \ RoleTemp \ iisexpress" que tenía un archivo de registro con contenido que se veía así (tenga en cuenta que he cambiado mi punto final de nuevo al puerto 80 , por lo que la aplicación IIS Express ahora está nuevamente en el puerto 81):

Solicitud iniciada: "GET" 127.0.0.1:81/Home/AboutSolicitud finalizada: 127.0.0.1:81/Home/About con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/ContactSolicitud finalizada: 127.0.0.1:81/Home/Contact con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/ContactSolicitud finalizada: 127.0.0.1:81/Home/Contact con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/ContactSolicitud finalizada: 127.0.0.1:81/Home/Contact con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/AboutSolicitud finalizada: 127.0.0.1:81/Home/About con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/AboutSolicitud finalizada: 127.0.0.1:81/Home/About con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/AboutSolicitud finalizada: 127.0.0.1:81/Home/About con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/ContactSolicitud finalizada: 127.0.0.1:81/Home/Contact con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/ContactSolicitud finalizada: 127.0.0.1:81/Home/Contact con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/ContactSolicitud finalizada: 127.0.0.1:81/Home/Contact con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/AboutSolicitud finalizada: 127.0.0.1:81/Home/About con estado HTTP 200.0Solicitud iniciada: "GET" 127.0.0.1:81/Home/ContactSolicitud finalizada: 127.0.0.1:81/Home/Contact con estado HTTP 200.0

Una vez más, simplemente estaba alternando entre las páginas Acerca y Contacto, por lo que, desde el registro, se puede ver que una única solicitud de punto final de rol web a veces dio lugar a que el rol web invocara la aplicación IIS varias veces. ¡Ahora busquemos algunos registros de roles web de nivel superior para descubrir por qué está haciendo esto :)!

Respuestas a la pregunta(1)

Su respuesta a la pregunta