我正在使用C#构建一个玩具数据库,以了解有关编译器,优化器和索引技术的更多信息.
我想保持(至少读取)将页面带入缓冲池的请求之间的最大并行度,但我对如何在.NET中实现这一点感到困惑.
以下是一些选项以及我遇到的每个问题:
使用System.IO.FileStream
和BeginRead
方法
但是,文件中的位置不是参数BeginRead
,它是FileStream
(通过Seek
方法设置)的属性,因此我一次只能发出一个请求,并且必须在一段时间内锁定流.(或者我呢?文档不清楚如果我只在Seek
和BeginRead
来电之间保持锁定而在呼叫之前发布它会发生什么会发生什么EndRead
.有人知道吗?)我知道怎么做,我只是不确定它是最好的办法.
似乎还有另一种方法,以System.Threading.Overlapped
结构为中心,P\Invoke到ReadFileEx
kernel32.dll中的 函数.
不幸的是,样本很少,特别是在托管语言中.这条路线(如果它可以完全工作)显然也涉及ThreadPool.BindHandle
线程池中的方法和IO完成线程.我得到的印象是,这是在Windows下处理这种情况的制裁方式,但我不理解它,我找不到有助于未经证实的文档的入口点.
别的什么?
在评论中,雅各布建议FileStream
为每次飞行中的阅读创建一个新的.
将整个文件读入内存.
如果数据库很小,这将起作用.代码库很小,还有很多其他低效率,但数据库本身却没有.我还想确保我正在处理处理大型数据库所需的所有簿记(事实证明这是复杂性的一个重要部分:分页,外部排序......)我担心它可能也是如此容易不小心作弊.
编辑
澄清为什么我对解决方案1持怀疑态度:从BeginRead到EndRead一直持有一个锁意味着我需要阻止任何想要启动读取的人,因为另一个读取正在进行中.这感觉不对,因为启动新读取的线程(通常)可以在结果可用之前再做一些工作.(实际上,只是写这个让我想出一个新的解决方案,我作为一个新的答案.)
我不确定为什么选项1对你不起作用.请记住,您不能让两个不同的线程同时尝试使用相同的FileStream - 这样做肯定会导致您遇到问题.BeginRead/EndRead旨在让您的代码继续执行,同时发生潜在的昂贵IO操作,而不是启用对文件的某种多线程访问.
所以我建议你寻求然后做一个初读.