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