Llamar a métodos basados en tareas desde ASMX

Tengo una experiencia reciente que me gustaría compartir que puede ser útil para cualquier persona que tenga que mantener un servicio web ASMX heredado que debe actualizarse para llamar a métodos basados en tareas.

Recientemente he estado actualizando un proyecto ASP.NET 2.0 que incluye un servicio web ASMX heredado a ASP.NET 4.5. Como parte de la actualización, introduje una interfaz API web para permitir la automatización avanzada de la aplicación. El servicio ASMX tiene que coexistir con la nueva API para la compatibilidad con versiones anteriores.

Una de las funciones de la aplicación es poder solicitar datos de fuentes de datos externas (historiadores de plantas industriales, servicios web a medida, etc.) en nombre de la persona que llama. Como parte de la actualización, reescribí partes sustanciales de la capa de acceso a datos para solicitar datos asincrónicamente usando un patrón asincrónico basado en tareas. Dado que no es posible usar aync / await en un servicio ASMX, modifiqué los métodos ASMX para realizar llamadas de bloqueo a los métodos asincrónicos, es decir, llamar al método basado en la tarea y luego usar Task.WaitAll para bloquear el hilo hasta que la tarea se complete.

Al llamar a cualquier método ASMX que llamaba a un método que devolvía Tarea o Tarea <T> debajo del capó, descubrí que la solicitud siempre agotaba el tiempo de espera. Cuando revisé el código, pude ver que el código asincrónico se estaba ejecutando con éxito, pero la llamada a Task.WaitAll nunca detectó que la tarea se había completado.

Esto causó un gran dolor de cabeza: ¿cómo podría el servicio ASMX coexistir felizmente con las nuevas capacidades asíncronas de acceso a datos?