Pregunta

Tengo un servicio web ASP.NET que hace un trabajo pesado, como por ejemplo, algunas operaciones de archivo, o la generación de hojas de Excel a partir de un montón de informes de Crystal. No quiero que me bloqueen llamando a este servicio web, por eso quiero hacer que el servicio web sea asincrónico. Además, quiero llamar a este servicio web desde una página web, y quiero algún mecanismo que me permita seguir encuestando el servidor para que pueda mostrar algún indicador de progreso en la pantalla, como por ejemplo, la cantidad de archivos que Se han procesado. Tenga en cuenta que no deseo recibir una notificación al finalizar la llamada al método web, sino que quiero un estado de progreso en vivo. ¿Cómo lo hago?

¿Fue útil?

Solución

Escriba un método separado en el servidor que pueda consultar al pasar el ID del trabajo que se ha programado y que devuelve un valor aproximado entre 0-100 (o 0.0 y 1.0, o lo que sea) de cuán avanzado está .

Por ejemplo, en el estilo REST, puede hacer una solicitud GET para http://yourserver.com/app/jobstatus/4133/ que devolvería un simple '52' como text / plain . Entonces, solo tienes que consultar cada (¿segundo? ¿Dos segundos? ¿Diez segundos?) Para ver qué tan avanzado está.

La forma en que realmente se logra la supervisión en el backend depende en gran medida de cuál sea su proceso y cómo funciona.

Otros consejos

Creo que el servicio web XML es lento, por lo que al crear múltiples métodos y sondeo , el progreso será extremadamente lento y generará una gran carga en el servidor. No lo haría en el entorno de producción. Veo los mismos (pero más pequeños) problemas con el sondeo de la base de datos.

Prueba extensiones de SOAP en su lugar. Implementa un modelo impulsado por eventos. Consulte Cómo agregar una barra de progreso a su aplicación de cliente de servicio web en MSDN .

También puede usar SoapExtensions para notificar a su cliente de la descarga / progreso del proceso. El servidor puede enviar eventos al cliente. No se debe cambiar nada en el cliente si no lo usa.

Permite algo como esto en tu cliente:

//...
private localhost.MyWebServiceService _myWebService = new localhost.MyWebServiceService ();
_myWebService.processDelegate += ProgressUpdate;
_myWebService.CallHeavyMethod();
//...

private void ProgressUpdate(object sender, ProgressEventArgs e)
{
  double progress = ((double)e.ProcessedSize / (double)e.TotalSize) * 100.00;
  //Show Progress...
}

Tener la inicial " iniciar la generación de informes " la llamada del servicio web crea una tarea en un grupo de tareas y devuelve a la persona que llama el ID de la tarea.

Luego, proporcione otro método que devuelva el " porcentaje realizado " para un ID de tarea dado.

Proporcione un tercer método que devuelva el resultado real para una tarea completada.

La forma más sencilla sería que el servicio web actualice un campo en una base de datos con el progreso de la llamada, y luego cree un servicio web que consulte ese campo y devuelva el valor.

Haga que el servicio web devuelva algún tipo de ID de tarea o ID de sesión. Cree otro método web para consultar con esa ID, que devuelve la información necesaria (% de finalización, lista de archivos, lo que sea). Encuesta este método en algún intervalo del cliente.

Use una base de datos para almacenar la información del proceso, si lo hace en la memoria del servicio web, esto no se ajustará bien en el entorno de la granja de servidores web, ya que puede suceder que la tarea se ejecute en otro servidor, que el que está sondeo.

EDITAR: acabo de ver otra respuesta similar, y comentarla. El comentarista tiene razón: puede usar la tabla en la memoria para evitar las operaciones del disco, pero sigue usando un servidor de db separado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top