문제

ConcurrentQueue의 TryDequeue는 대기열에 항목이 없으면 false를 반환합니다.

대기열이 비어 있으면 대기열에 새 항목을 추가 할 때까지 내 대기열이 대기하고 새 하나를 삭제하고 프로세스가 계속해서 그렇게 계속됩니다.

모니터를 사용해야합니다. 에서 monitor.Ener, Wait, Pulse 또는 더 나은 옵션

도움이 되었습니까?

해결책

이이 방법이 아닙니다 BlockingCollection

이해할 때, ConcurrentQueue를이 중 하나와 랩핑 한 다음 .

다른 팁

주기적으로 큐의 요소 수를 확인하고 요소 수가 0보다 큰 경우 예를 들어 신호를 제공합니다.대기열이 비어있을 때까지 요소를 삭제하는 스레드에 ManualReseTevent.

여기에 대한 의사 코드가 있습니다 :

스레드 확인 :

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

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

덱스 큐 스레드 :

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

DeQueueUntilQueueEmpty에서 잠금을 사용하는 것을 고려하십시오.

blockingCollection . 를 사용할 수 있습니다.

그런 식을하십시오 :

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;
}
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top