Reputation: 647
I've an event fired multiple times. Each firing spawn a thread that will process an input and these processing have to be sequential.
This is the code:
void TcpClient_DataRead(object sender, DataReadEventArgs e)
{
//the first stops the other ones
this.parsingXML.WaitOne();
//processing the string
string pop = Encoding.ASCII.GetString(e.Data);
BufferizeXML(pop);
//restoring execution
this.parsingXML.Set();
}
Here I've tried to make the other thread wait and restore after the execution of the previous one has ended, but this solution restore all the waiting thread.
Is there a method for manage a queue of waiting thread?
Upvotes: 1
Views: 2281
Reputation: 7438
Start a task when application initialize, create concurrent queue, start data read task and bind event handler after it.
ConcurrentQueue<DataReadEventArgs> list;
Init()
{
var list = new ConcurrentQueue<DataReadEventArgs>();
Task.Factory.StartNew(()=>DataRead());
OnTcpClientDataRead += TcpClient_DataRead;
}
// PUBLISHER
void TcpClient_DataRead(object sender, DataReadEventArgs e)
{
list.Enqueue(e);
}
An always running job which process BufferizeXml for all data in queue, if list is empty it takes pause of a second and continue again //CONSUMER
void DataRead()
{
while(true)
{
if (list.Count ==0)
Thread.Sleep(1000);
string pop;
list.TryDequeue(out pop);
Encoding.ASCII.GetString(pop);
BufferizeXML(pop);
}
}
You can put some variable and let the while loop check it for breaking the iteration.
Upvotes: 0
Reputation: 33252
This is a typical case you can use the publish-consumer pattern.
You can use a Queue<T>
or ConcurrentQueue<T>
to queue the events, and then have a single thread dequeuing and executing the actual handling. You just need a single thread since you said they need to be executed sequentially, this will avoid the time in creating threads. Just keep an eye to the fact that you must lock the queue access if you can't ( mostly because you are forced to use older version of the framework ) use the concurrent version.
Upvotes: 5