Foros del Web » Programación para mayores de 30 ;) » .NET »

Semaforo en llamadas asincronas

Estas en el tema de Semaforo en llamadas asincronas en el foro de .NET en Foros del Web. Hola, Estoy intentando realizar un semaforo para llamadas asincronas, me explico. Tengo un programa que es un servicio de windows al que distintos usuarios realizan ...
  #1 (permalink)  
Antiguo 19/09/2008, 03:08
Avatar de elangelcaido  
Fecha de Ingreso: septiembre-2003
Ubicación: Oviedo
Mensajes: 1.068
Antigüedad: 20 años, 7 meses
Puntos: 4
Exclamación Semaforo en llamadas asincronas

Hola,

Estoy intentando realizar un semaforo para llamadas asincronas, me explico.

Tengo un programa que es un servicio de windows al que distintos usuarios realizan peticiones por HTTP. el metodo que escucha es este:

Código:
private void ThreadProc()
        {
            try{
                HttpListener listener = new HttpListener();
                listener.Prefixes.Add(uriPrefix);
                listener.Start();

                while (listening){

                    IAsyncResult result = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
                    result.AsyncWaitHandle.WaitOne();

                }
            } catch (Exception ex) {
                .....
            }
        }
El método ListenerCallback realiza una tarea que debe ser utilizada únicamente por un usuario a la vez, es decir, necesito semaforos. Aquí esta el problema que tengo.

Para el tema de los semaforos, segun lo que yo entiendo, debo crear el objeto semaforo dentro la funcion que se llama de manera asincrona (en el método ThreadProc()), o sea, en ListenerCallback. Ademas, en ListenerCallback, debo lanzar el thread y hacer un Release despues. A dicho thread le indico la funcion que debe ejecutar para esperar en el semaforo y cuando le toque realizar LA OPERACION QUE SOLO DEBE EJECUTAR UN USUARIO A LA VEZ.

Pongo el código.

Código:
public static void ListenerCallback(IAsyncResult result) {

try {
                HttpListener listener = (HttpListener)result.AsyncState;
                HttpListenerContext context = listener.EndGetContext(result);
                WindowsIdentity identity = (WindowsIdentity)context.User.Identity;

                cola = new Semaphore(0, 3);// cola es un objeto static Semaphore declarado en la clase

                MiObjeto o = new MiObjeto();

                Thread t = new Thread(new ParameterizedThreadStart(gestion));
                cont++;
                t.Name = cont.ToString();
                t.Start(o);

                engine.Run(request, response);

                Random r = new Random(DateTime.Now.Millisecond);
                Thread.Sleep(r.Next(100, 3000));

                cola.Release(1);

                context.Response.Close();
            } catch (Exception ex) {
                ....
            }
}

public static void gestionCache(object obj) {

            try {
                cola.WaitOne();//esperamos a que nos toque para ejecutar lo nuestro

                Random r = new Random(DateTime.Now.Millisecond);
                Thread.Sleep(r.Next(100, 3000));

                //AQUI IRIA LA OPERACION QUE SOLO PUEDE REALIZAR UN USUARIO A LA VEZ

                cola.Release();

            } catch (Exception ex) {
                ....
            }
}
El caso es que el semaforo no funciona correctamente. Me saltan muchas expeciones a causa de realizar un Release() cuando no debería realizarse.

¿Alguien puede aportar alguna luz?

Gracias por la ayuda.
__________________
Ta Luego! Al final sólo puede quedar uno...
________
lukos.org
  #2 (permalink)  
Antiguo 23/09/2008, 10:05
Avatar de diegopedro  
Fecha de Ingreso: agosto-2006
Ubicación: Santiago
Mensajes: 120
Antigüedad: 17 años, 8 meses
Puntos: 0
Respuesta: Semaforo en llamadas asincronas

Es una sujerencia, se me ocurre lo siguiente, mientras un usuario este procesando, no aceptar solicitudes.


public PROP_OCUPADO as boolean


PROP_OCUPADO=true
private void ThreadProc()
{
try{
HttpListener listener = new HttpListener();
listener.Prefixes.Add(uriPrefix);
listener.Start();

while (listening){
if PROP_OCUPADO then
PROP_OCUPADO=false
IAsyncResult result = listener.BeginGetContext(new AsyncCallback
(ListenerCallback), listener);
result.AsyncWaitHandle.WaitOne();
PROP_OCUPADO=true
ens if


}
} catch (Exception ex) {
.....
}
}
__________________
Es facil apretar tornillos, pero lo complejo es saber que tornillo apretar
  #3 (permalink)  
Antiguo 23/09/2008, 15:15
Avatar de elangelcaido  
Fecha de Ingreso: septiembre-2003
Ubicación: Oviedo
Mensajes: 1.068
Antigüedad: 20 años, 7 meses
Puntos: 4
Respuesta: Semaforo en llamadas asincronas

De verdad, muchas gracias por hacer tu sugerencia. Lo probaré.
__________________
Ta Luego! Al final sólo puede quedar uno...
________
lukos.org
  #4 (permalink)  
Antiguo 24/09/2008, 13:28
Avatar de diegopedro  
Fecha de Ingreso: agosto-2006
Ubicación: Santiago
Mensajes: 120
Antigüedad: 17 años, 8 meses
Puntos: 0
Respuesta: Semaforo en llamadas asincronas

Si te resulto alguna alternativa, favor comentala ya que a muchos nos interesa el tema

Saludos
__________________
Es facil apretar tornillos, pero lo complejo es saber que tornillo apretar
  #5 (permalink)  
Antiguo 25/09/2008, 07:07
Avatar de elangelcaido  
Fecha de Ingreso: septiembre-2003
Ubicación: Oviedo
Mensajes: 1.068
Antigüedad: 20 años, 7 meses
Puntos: 4
Respuesta: Semaforo en llamadas asincronas

Al final no me funcionó.

Todo esto era para sincronizar el acceso unitario a una estructura de datos. Se me ocurrió otra solución para el acceso unitario a la estructura de datos.

Las tablas hash (Hashtable) de C# tienen un método SyncRoot para que se pueda bloquear el acceso a la tabla hash (estructura de datos). Por ejemplo:


Código:
Hashtable ht=new Hashtable();

lock(ht.SyncRoot){

//aquí dentro todo lo que se quiera hacer... 
//...y que sólo lo pueda hacer un usuario a la vez

}
De esta manera ya, la propia estructura de datos tabla hash, implementa el sistema de semáforos.

Ha sido la mejor solución que he encontrado.

Gracias por la ayuda y espero que a alguien le sirva.
__________________
Ta Luego! Al final sólo puede quedar uno...
________
lukos.org
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:03.