Thread-safe File d'attente FIFO/Tampon
J'ai besoin de mettre en œuvre une sorte de tâche de la mémoire tampon. Exigences de base sont:
- Les tâches de processus dans un seul thread d'arrière-plan
- Recevoir des tâches à partir de plusieurs threads
- Processus ont TOUS reçu des tâches à savoir assurez-vous que le tampon est vidé de tampon des tâches après un signal d'arrêt est reçu
- Ordre des tâches reçues par thread doit être maintenue
Je pensais de la mise en œuvre à l'aide d'une File d'attente comme ci-dessous. Aimeraient des commentaires sur la mise en œuvre. Existe-il d'autres des idées brillantes pour mettre en œuvre une telle chose?
public class TestBuffer
{
private readonly object queueLock = new object();
private Queue<Task> queue = new Queue<Task>();
private bool running = false;
public TestBuffer()
{
}
public void start()
{
Thread t = new Thread(new ThreadStart(run));
t.Start();
}
private void run()
{
running = true;
bool run = true;
while(run)
{
Task task = null;
//Lock queue before doing anything
lock (queueLock)
{
//If the queue is currently empty and it is still running
//we need to wait until we're told something changed
if (queue.Count == 0 && running)
{
Monitor.Wait(queueLock);
}
//Check there is something in the queue
//Note - there might not be anything in the queue if we were waiting for something to change and the queue was stopped
if (queue.Count > 0)
{
task = queue.Dequeue();
}
}
//If something was dequeued, handle it
if (task != null)
{
handle(task);
}
//Lock the queue again and check whether we need to run again
//Note - Make sure we drain the queue even if we are told to stop before it is emtpy
lock (queueLock)
{
run = queue.Count > 0 || running;
}
}
}
public void enqueue(Task toEnqueue)
{
lock (queueLock)
{
queue.Enqueue(toEnqueue);
Monitor.PulseAll(queueLock);
}
}
public void stop()
{
lock (queueLock)
{
running = false;
Monitor.PulseAll(queueLock);
}
}
public void handle(Task dequeued)
{
dequeued.execute();
}
}
double possible de les Files d'attente Et Attendre Poignées en C#
Voulez-vous autoriser enqueueing après arrêt() a été appelé?
Voulez-vous autoriser enqueueing après arrêt() a été appelé?
OriginalL'auteur user1300560 | 2012-09-11
Vous devez vous connecter pour publier un commentaire.
Vous pouvez réellement gérer cela avec le dehors-de-le-boîte de BlockingCollection.
Il est conçu pour avoir 1 ou plusieurs producteurs, et 1 ou plusieurs consommateurs. Dans votre cas, vous disposez de plusieurs producteurs et consommateurs.
Lorsque vous recevez un signal d'arrêt, ont que gestionnaire de signal
Le thread consommateur continuera à s'exécuter en file d'attente jusqu'à ce que tous les éléments sont supprimés et transformés, puis il va rencontrer la condition que le BlockingCollection est terminée. Quand le fil de rencontres de condition, il vient de sorties.
OriginalL'auteur Eric J.
Vous devriez penser à ConcurrentQueue, qui est FIFO, en fait. Si ne vous convient pas, essayer quelques-uns de ses parents Thread-Safe Collections. En utilisant ces derniers vous pouvez éviter certains risques.
OriginalL'auteur Qerts
Je vous suggère de prendre un coup d'oeil à TPL DataFlow. Type bufferblock est ce que vous cherchez, mais il offre beaucoup plus.
OriginalL'auteur spender
Regarde mon léger de la mise en œuvre de threads file d'attente FIFO, il ne bloque rien et utilise threadpool - de mieux que de créer ses propres fils dans la plupart des cas. https://github.com/Gentlee/SerialQueue
Utilisation:
OriginalL'auteur Alexander Danilov
Vous pouvez utiliser Rx .NET 3.5 pour cela. Il aurait pu ne jamais sortir de RC, mais je crois qu'il est stable* et utilisé par de nombreux systèmes de production. Si vous n'avez pas besoin d'un Sujet que vous pourriez trouver les primitives (comme les collections simultanées).NET 3.5, vous pouvez l'utiliser n'a pas l'expédier avec le .NET Framework jusqu'à 4.0.
Alternative à Rx (Reactive Extensions).net 3.5
* - Nit sélecteur du coin: l'Exception peut-être de l'heure avancée de fenêtrage, qui est hors de portée, mais les tampons (en nombre et en temps), de commande et les planificateurs sont tous stables.
OriginalL'auteur yzorg