Question

Le TryDequeue dans ConcurrentQueue retournera faux si aucun élément dans la file d'attente.

Si la file d'attente est vide, j'ai besoin que ma file d'attente attend que un nouvel élément soit ajouté dans la file d'attente et qu'il désira ce nouveau, et le processus se poursuivra comme ça.

Dois-je utiliser moniteur.enter, attendre, impulser ou de meilleures options en C # 4.0

Était-ce utile?

La solution

N'est-ce pas quoi BlockingCollection est conçu pour?

Si je comprends bien, vous pouvez envelopper votre concurrentque avec l'un d'eux, puis appeler Prendre.

Autres conseils

Vous pouvez vérifier périodiquement le nombre d'éléments dans la file d'attente et lorsque le nombre d'éléments est supérieur à zéro, vous donnez un signal en utilisant le manualresivent manual-resentient au fil qui désactive le ou les éléments jusqu'à ce que la file d'attente soit vide.

Voici le code pseudo pour ceci:

Vérifier le fil:

while(true)
{
  int QueueLength = 0;
  lock(Queue)
  {
    queueLength = Queue.Length;
  }

  if (Queue.Length > 0)
  {
    manualResetEvent.Set();
  }
  else
  {
    Thread.Sleep(...);
  }       
}    

Fil de désagréation:

while(true)
{
  if(manualResetEvent.WaitOne(timeout))
  {
    DequeueUntilQueueEmpty();
  }
}

Envisagez également d'utiliser le verrouillage dans le dequeueuntilqueueEympty.

Vous pouvez utiliser BlockingCollection.

Faites quelque chose comme ça:

private BlockingCollection<string> rowsQueue;
private void ProcessFiles() {
   this.rowsQueue = new BlockingCollection<string>(new ConcurrentBag<string>(), 1000);
   ReadFiles(new List<string>() { "file1.txt", "file2.txt" });


   while (!this.rowsQueue.IsCompleted || this.rowsQueue.Count > 0)
   {
       string line = this.rowsQueue.Take();

       // Do something
   }
}

private Task ReadFiles(List<string> fileNames)
{
    Task task = new Task(() =>
    {
        Parallel.ForEach(
        fileNames,
        new ParallelOptions
        {
            MaxDegreeOfParallelism = 10
        },
            (fileName) =>
            {
                using (StreamReader sr = File.OpenText(fileName))
                {
                    string line = String.Empty;
                    while ((line = sr.ReadLine()) != null)
                    {
                           this.rowsQueue.Add(line);
                    }
                }
            });

        this.rowsQueue.CompleteAdding();
    });

    task.Start();

    return task;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top