我正在用 C# 构建一个玩具数据库,以了解有关编译器、优化器和索引技术的更多信息。
我想在将页面带入缓冲池的(至少读取)请求之间保持最大并行度,但我对如何在 .NET 中最好地实现这一点感到困惑。
以下是一些选项以及我遇到的问题:
用途
System.IO.FileStream
及BeginRead
方法但是,文件中的位置不是 的参数
BeginRead
,它是FileStream
(通过Seek
方法设置)的属性,所以我一次只能发出一个请求,并且必须在持续时间内锁定流。(或者我是吗?文档不清楚如果我只在Seek
andBeginRead
调用之间持有锁但在调用之前释放它会发生什么EndRead
。有人知道吗?)我知道该怎么做,我只是不确定它是最好的办法。似乎还有另一种方式,以
System.Threading.Overlapped
结构和 P\Invoke 为 中心ReadFileEx
在 kernel32.dll 中的函数。不幸的是,缺乏样本,尤其是在托管语言中。这条路线(如果它可以工作的话)显然还涉及
ThreadPool.BindHandle
线程池中的方法和IO完成线程。我的印象是这是在 Windows 下处理这种情况的认可方式,但我不明白,我找不到对初学者有帮助的文档的入口点。还有什么?
在评论中,雅各布建议
FileStream
为飞行中的每一次阅读创建一个新的。将整个文件读入内存。
如果数据库很小,这将起作用。代码库很小,还有很多其他的低效率,但数据库本身不是。我还想确保我正在做处理大型数据库所需的所有簿记(事实证明这是复杂性的很大一部分:分页、外部排序......)我担心它可能也是容易不小心作弊。
编辑
澄清为什么我对解决方案 1 持怀疑态度:从 BeginRead 到 EndRead 一直持有一个锁意味着我需要阻止任何想要启动读取的人,因为另一次读取正在进行中。这感觉不对,因为启动新读取的线程可能(通常)能够在结果可用之前做更多的工作。(实际上,仅仅写这篇文章就让我想到了一个新的解决方案,我把它作为一个新的答案。)