[英]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 是不使用 Windows kernel 信號量的信號量 class 的輕量級替代品
https://docs.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netcore-3.1
You can read the whole code for BlockingCollection
here: https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.