我正在开发一个简单的文件记录器,遇到线程安全问题,并且正在研究其他人的工作方式。我遇到了使用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
,直到调用.CompleteAdding
BlockingCollection。
我不知道为什么这样做会如此,以及如何以及是否是一个好的方法。集合为空时线程做什么,是否检查每个刻度?那不是资源丰富吗?
它用于SemiphoreSlim
等待GetConsumingEnumerable
并Release
在添加项目时调用(高度简化)。
SemaphoreSlim是不使用Windows内核信号量的Semaphore类的轻量级替代方案
https://docs.microsoft.com/zh-cn/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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句