如果队列中没有项目,ConcurrentQueue中的TryDequeue将返回false。
如果队列是空的,我需要我的队列等待,直到队列中添加了新的项,并将新项从队列中移出,该过程将继续。
我应该使用C# 4.0中的monitor.enter、wait、pulse或任何更好的选项吗
发布于 2011-02-16 16:45:26
这不就是BlockingCollection的设计目标吗?
据我所知,您可以用其中一个来包装您的ConcurrentQueue,然后调用Take。
发布于 2018-08-15 06:51:15
您可以使用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;
}
发布于 2011-02-16 16:41:24
您可以定期检查队列中元素的数量,当元素数量大于零时,您可以使用例如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中使用锁。
https://stackoverflow.com/questions/5014087
复制相似问题