Ejercicio I02 - Simulador de atención a clientes
Consigna
Se creará una solución para simular la atención paralela de clientes en dos cajas de un negocio.

Empezar creando un proyecto de biblioteca de clases y declarar las siguientes clases:
Caja
Tendrá un atributo estático de tipo
Randomque será instanciado en un constructor estático.Tendrá un atributo de tipo
Queue<string>llamadoclientesALaEspera.Tendrá un atributo de tipo
stringllamadonombreCajaque será expuesto por una propiedad de sólo lectura.Tendrá una propiedad
CantidadDeClientesALaEsperaque retornará la cantidad actual de elementos en la colaclientesALaEspera.El único constructor de instancia deberá:
- Instanciar la cola
clientesALaEspera. - Recibir el nombre de la caja y asignarlo al atributo
nombreCaja. - Recibir la referencia a un método que no retorne nada y reciba un objeto de tipo
Cajay otro de tipostring. Dicha referencia deberá asignarse a un campo privado llamadodelegadoClienteAtendido. Declarar un nuevo tipo delegado que permita cumplir con este punto.
- Instanciar la cola
Tendrá un método
AgregarClientecon visibilidadinternalque recibirá un cliente y lo agregará aclientesALaEspera.Tendrá un método
IniciarAtencioncon visibilidadinternalque deberá iniciar la atención de clientes en un sub-proceso paralelo. Este método no recibirá nada y retornará la instancia deTaskque se haya utilizado.- La tarea de atención de clientes:
- Se seguirá ejecutando de manera iterativa hasta que se cierre la aplicación.
- Si hay clientes a la espera (se puede verificar con el método
Anyde la biblioteca LINQ (System.Linq) que retornatruesi una colección contiene algún elemento.):- Se retirará al siguiente cliente de la cola
clientesALaEspera. - Se invocará al método referenciado por
delegadoClienteAtendido, pasándole la instancia de esa misma caja y el cliente que se recuperó de la cola. - Se suspenderá el hilo por un periodo de 1 a 5 segundos de manera aleatoria (usar atributo
Random).
- Se retirará al siguiente cliente de la cola
- La tarea de atención de clientes:
Negocio
Requerirá la instalación del paquete NuGet
NameGeneratoren el proyecto de biblioteca de clases.Crear un atributo estático de tipo
RealNameGenerator(namespaceNameGenerator.Generators) que será instanciado en un constructor estático.Tendrá un atributo de tipo
ConcurrentQueue<string>llamadoclientes. Este tipo de dato es la versión del tipoQueueque cuenta con seguridad para trabajar con hilos (es thread-safe).
Tendrá un atributo de tipo
List<Caja>llamadocajas.El único constructor de instancia deberá:
- Recibirá una lista de cajas y la asignará al atributo
cajas. - Instanciará el atributo
clientes.
- Recibirá una lista de cajas y la asignará al atributo
Tendrá un método público
ComenzarAtencionque:- Lo primero que hará será abrir todas las cajas del negocio, llamando al método
IniciarAtencionde cada caja. - En segundo lugar iniciará una tarea concurrente (en otro hilo) de simulación de clientes.
- La tarea se seguirá ejecutando de manera iterativa hasta que se cierre la aplicación.
- Esta tarea deberá agregar un nuevo cliente a la cola
clientescada un segundo (suspender 1 segundo el hilo). - Para generar el nuevo cliente utilizar el método
Generatedel atributo estático de tipoRealNameGenerator.
- En tercer lugar iniciará una tarea concurrente (en otro hilo) de asignación de cajas. Esta tarea asignará al siguiente cliente en la cola
clientesa la caja con MENOS clientes .- La tarea se seguirá ejecutando de manera iterativa hasta que se cierre la aplicación.
- Para saber cuál es la caja con menos clientes, ordenar las cajas de forma ascendente en base a la propiedad
CantidadDeClientesALaEspera.- Utilizar el método
OrderByde la biblioteca LINQ (System.Linq), que tiene como argumento un delegado que recibe un cliente y retorna el valor esa instancia por el que se debe ordenar (en este caso la propiedadCantidadDeClientesALaEspera). Ante cualquier duda, consulte la documentación.
- Utilizar el método
- Una vez ordenada la lista debemos quedarnos con la caja con menos clientes a la espera, es decir, la primera luego de haber ordenado de forma ascendente. Para esto utilizar el método
Firstde la biblioteca LINQ (System.Linq), que retorna el primer elemento de una colección. Ante cualquier duda, consulte la documentación. - Para recuperar el cliente de la cola
clientesutilizar el métodoTryDequeue. - Si el método
TryDequeueretornó unstringque no sea nulo ni espacios en blanco (puede usar el método estáticostring.IsNullOrWhiteSpace), agregar el cliente a la caja utilizando el métodoAgregarClientede la caja.
- No recibirá nada y retornará la lista de sub-procesos iniciados por el negocio (
List<Task>). Esta lista debe incluir los hilos iniciados para la simulación de clientes, la asignación de cajas y los retornados por el métodoIniciarAtencionde las cajas.
- Lo primero que hará será abrir todas las cajas del negocio, llamando al método
Crear una aplicación de consola y en el método Main:
Instanciar el delegado declarado en
Cajacon una expresión lambda que imprima un mensaje en la consola con el siguiente formato:[Hora actual con formato HH:MM:ss] - Hilo [Id del hilo actual (usar `Task.CurrentId`)] - [Nombre de la caja] - Atendiendo a [nombre del cliente]. Quedan [cantidad de clientes a la espera] clientes en esta caja.Ejemplo de resultado esperado: "13:10:31 - Hilo 1 - Caja 01 - Atendiendo a Christopher Torres. Quedan 2 clientes en esta caja."
Reemplazar el texto entre corchetes por el dato correspondiente.
Instanciar 2 cajas, pasándole al constructor el delegado instanciado en el punto anterior.
Instanciar una variable de tipo
List<Caja>y agregarle las cajas creadas en el punto anterior.Instanciar un
Negocioy pasarle la lista de cajas del punto anterior.Imprimir por consola el texto: "Asignando cajas..."
Llamar al método
ComenzarAtenciondeNegocio.Utilizar el método estático
WaitAlldeTaskpara que la aplicación no se cierre mientras los hilos retornados por el métodoComenzarAtencionestén corriendo. Tener en cuenta queWaitAllrecibe un array como argumento y no una lista (usar el métodoToArraypara convertir la lista en un array).
Resolución
| Video | Código |
|---|