BlockingCollection 运行 上的 foreach 循环为何以及如何无限循环?
Why and how does a foreach-loop on BlockingCollection run infinite?
我正在开发一个简单的文件记录器,遇到了线程安全问题,并且正在研究其他人是如何做的。
我遇到了使用 BlockingCollection 作为队列和 foreach 循环来处理该队列的方法:
var queue = new BlockingCollection<string>(1024);
var t = Task.Factory.StartNew(() => {
foreach (var message in queue.GetConsumingEnumerable()) {
WriteMessageToFile(message);
}
}, TaskCreationOptions.LongRunning);
Dim queue = New BlockingCollection(Of String)(1024)
Dim t = Task.Factory.StartNew(Sub()
For Each message In queue.GetConsumingEnumerable()
WriteMessageToFile(message)
Next
End Sub, TaskCreationOptions.LongRunning)
这个 For Each 循环实际上 运行 是无限的。它处理我添加到 queue
的数据,直到我在 BlockingCollection 上调用 .CompleteAdding
。
我想知道为什么会这样,以及如何以及是否是一个好方法。
当集合为空时线程会做什么,它会检查每个滴答声吗?这不是资源繁重吗?
它使用 SemiphoreSlim
等待 GetConsumingEnumerable
并在添加项目时调用 Release
(高度简化)。
SemaphoreSlim is a lightweight alternative to the Semaphore class that
doesn't use Windows kernel semaphores
https://docs.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netcore-3.1
您可以在此处阅读 BlockingCollection
的完整代码:https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs
我正在开发一个简单的文件记录器,遇到了线程安全问题,并且正在研究其他人是如何做的。 我遇到了使用 BlockingCollection 作为队列和 foreach 循环来处理该队列的方法:
var queue = new BlockingCollection<string>(1024);
var t = Task.Factory.StartNew(() => {
foreach (var message in queue.GetConsumingEnumerable()) {
WriteMessageToFile(message);
}
}, TaskCreationOptions.LongRunning);
Dim queue = New BlockingCollection(Of String)(1024)
Dim t = Task.Factory.StartNew(Sub()
For Each message In queue.GetConsumingEnumerable()
WriteMessageToFile(message)
Next
End Sub, TaskCreationOptions.LongRunning)
这个 For Each 循环实际上 运行 是无限的。它处理我添加到 queue
的数据,直到我在 BlockingCollection 上调用 .CompleteAdding
。
我想知道为什么会这样,以及如何以及是否是一个好方法。 当集合为空时线程会做什么,它会检查每个滴答声吗?这不是资源繁重吗?
它使用 SemiphoreSlim
等待 GetConsumingEnumerable
并在添加项目时调用 Release
(高度简化)。
SemaphoreSlim is a lightweight alternative to the Semaphore class that doesn't use Windows kernel semaphores
https://docs.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netcore-3.1
您可以在此处阅读 BlockingCollection
的完整代码:https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs