c# - que - vb net eventos
En.NET, ¿en qué tema se manejarán los eventos? (4)
A menos que hagas el marshaling, un evento se ejecutará en cualquier hilo que lo invoque; no hay nada de especial en la forma en que se invocan los eventos, y el hilo del productor no tiene un controlador de eventos, el hilo del productor simplemente dijo "hey, cuando dispare este evento, llame a esta función". No hay nada allí que provoque la ejecución del evento en el hilo BeginInvoke
, ni en su propio hilo (a menos que use BeginInvoke
lugar de invocar el delegado del evento normalmente, pero esto solo lo ejecutará en ThreadPool
).
Intenté implementar un patrón productor / consumidor en c #. Tengo un hilo de consumidor que supervisa una cola compartida y un hilo productor que coloca elementos en la cola compartida. El subproceso productor está suscrito para recibir datos ... es decir, tiene un controlador de eventos, y simplemente se sienta y espera a que se active un evento OnData (los datos se envían desde una API de terceros). Cuando obtiene los datos, los pega en la cola para que el consumidor pueda manejarlos.
Cuando el evento OnData se dispara en el productor, esperaba que fuera manejado por mi hilo productor. Pero eso no parece ser lo que está sucediendo. ¡El evento OnData parece como si estuviera siendo manejado en un nuevo hilo en su lugar! ¿Es así como .net siempre funciona ... los eventos se manejan en su propio hilo? ¿Puedo controlar qué hilo manejará los eventos cuando se generan? ¿Qué ocurre si cientos de eventos se generan casi simultáneamente ... tendrían cada uno su propio hilo?
Criar un evento con Invoke
es lo mismo que llamar a un método: se ejecuta en el mismo hilo que lo planteaste.
Criar un evento con BeginInvoke
usa ThreadPool
. Aquí hay algunos detalles menores
Después de volver a leer la pregunta, creo que entiendo el problema ahora. Básicamente, tienes algo como esto:
class Producer
{
public Producer(ExternalSource src)
{
src.OnData += externalSource_OnData;
}
private void externalSource_OnData(object sender, ExternalSourceDataEventArgs e)
{
// put e.Data onto the queue
}
}
Y luego tienes un hilo de consumo que saca cosas de esa cola. El problema es que el evento OnData es disparado por su objeto ExternalSource
, en cualquier hilo en el que se esté ejecutando.
Los event
C # son básicamente una colección de delegados fácil de usar y el hecho de "disparar" un evento hace que el tiempo de ejecución recorra todos los delegados y los active de uno en uno.
Por lo tanto, se llama al controlador de eventos de OnData en el hilo en el que se está ejecutando ExternalSource
.
tienes que usar manejadores de prevención automática para este problema ... en prevención automática, cuando los productores activan la señal, entonces el consumidor restablece su señal y consume ... después de consumir, consume la señal establecida, solo el productor produce ...
AutoResetEvent pro = new AutoResetEvent(false);
AutoResetEvent con = new AutoResetEvent(true);
public void produser()
{
while(true)
{
con.WaitOne();
pro.Set();
}
}
public void consumer()
{
while (true)
{
pro.WaitOne();
.................****
con.Set();
}
}
private void button1_Click(object sender, EventArgs e)
{
Thread th1 = new Thread(produser);
th1.Start();
Thread th2 = new Thread(consumer);
th2.Start();
}