C#中的推荐方法是同时异步读取单个文件中的多个位置

C#中的推荐方法是同时异步读取单个文件中的多个位置,c#,multithreading,asynchronous,filestream,C#,Multithreading,Asynchronous,Filestream,我使用的是只读数据文件(例如100s的gig),每个文件包含64K的数据块。我想构建一个内存缓存来处理每个服务请求所需的10s-100s块读取 基本异步非线程安全读取如下所示: public async Task<byte[]> Read(int id) { FStream.Seek(CalcOffset(id), SeekOrigin.Begin); var ba = new byte[64 * 1024]; await FStream.ReadAsync(

我使用的是只读数据文件(例如100s的gig),每个文件包含64K的数据块。我想构建一个内存缓存来处理每个服务请求所需的10s-100s块读取

基本异步非线程安全读取如下所示:

public async Task<byte[]> Read(int id)
{
    FStream.Seek(CalcOffset(id), SeekOrigin.Begin);
    var ba = new byte[64 * 1024];
    await FStream.ReadAsync(ba, 0, ba.Length);
    return ba;
}
公共异步任务读取(int-id)
{
Seek(CalcOffset(id),SeekOrigin.Begin);
var ba=新字节[64*1024];
等待FStream.ReadAsync(ba,0,ba.Length);
返回ba;
}
我无法锁定FStream以使上述线程安全(C#error“不能在lock语句体中等待”)。我无法删除wait而不丢失异步行为。我当前的解决方案已从文件流缓存中读取图形:

    private BufferBlock<FileStream> StreamRead;

    public async Task<FileStream> GetReadStream()
    {
        return await StreamRead.ReceiveAsync(TimeSpan.FromMilliseconds(-1));
    }

    public async Task ReleaseReadStream(FileStream stream)
    {
        await StreamRead.SendAsync(stream);
    }
私有缓冲块流读;
公共异步任务GetReadStream()
{
返回wait-StreamRead.ReceiveAsync(TimeSpan.frommilluses(-1));
}
公共异步任务ReleaseReadStream(文件流)
{
等待StreamRead.SendAsync(流);
}
这是构建多线程异步友好缓存的最佳方法吗?还有其他建议吗

我想建立一个内存缓存

你确定吗?:)

Windows在过去几十年中投入了大量的工作来实现操作系统内置的高性能文件缓存

在某些情况下,您可以为特定的用例进行更高效的缓存,但大多数情况下,这样做并不值得。我建议先测量一下

我无法锁定FStream以使上述线程安全(C#error“不能在lock语句体中等待”)

我的问题涉及是否/如何以异步方式对文件流执行多个并发读取

您可以使用
信号量LIM
作为
异步
兼容锁。语法有点笨拙,但它可以工作


另一方面,我还建议您查看内存映射文件。

您希望的是以某种方式查找文件,然后同时读取文件。这方面的奇特术语是执行“原子查找和读取”操作

Windows和Linux支持这种类型的操作。在Linux上,有一个函数名为,在Windows上,有一个函数名为。剩下的就是去处理这些电话。是啊,不好玩

我遇到了完全相同的问题,因此我将解决方案放入了一个库中。我的图书馆。它允许您同时进行原子查找和读取,并且比锁定文件流更快

using pread;

using var fileStream = new FileStream("my_file.txt", FileMode.OpenOrCreate);

var data = new byte[123];

var bytesWritten = P.Write(fileStream, (ReadOnlySpan<byte>)data, fileOffset: 0);
var bytesRead = P.Read(fileStream, (Span<byte>)data, fileOffset: 0);
使用pread;
使用var fileStream=newfilestream(“my_file.txt”,FileMode.OpenOrCreate);
变量数据=新字节[123];
var bytesWrite=P.Write(fileStream,(ReadOnlySpan)数据,fileOffset:0);
var bytesRead=P.Read(fileStream,(Span)数据,fileOffset:0);

如果您想获得这方面的帮助,您需要发布一些代码。如果是只读存储器,则AppedFile可能会有所帮助。您是否搜索过FileStream。Seek?已更新以添加代码。文件太多,无法加载到内存中。不是选项吗?让系统在正确的时间处理在正确的数据位中的分页,就好像所有数据都已加载一样。