簡體   English   中英

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 是不使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM