Ver Mensaje Individual
  #1 (permalink)  
Antiguo 19/09/2008, 03:08
Avatar de elangelcaido
elangelcaido
 
Fecha de Ingreso: septiembre-2003
Ubicación: Oviedo
Mensajes: 1.068
Antigüedad: 20 años, 8 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