使用 pinvoke 的多线程 ReadFile 调用给出 STATUS_INVALID_USER_BUFFER
Multithreaded ReadFile calls using pinvoke gives STATUS_INVALID_USER_BUFFER
我正在编写一些代码来绕过 FileStream 中的缓冲从二进制文件中读取块,因为它在使用 LockFileEx 锁定文件区域时会导致问题。此代码与来自参考源的 FileStream 中的实现几乎相同。
private unsafe int ReadFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, out int hr)
{
int r = 0;
int numBytesRead = 0;
fixed (byte* p = bytes)
{
r = Native.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
}
ReadFile 是这样导入的:
unsafe internal static extern int ReadFile(SafeFileHandle handle, byte* bytes,
int numBytesToRead, out int numBytesRead, IntPtr mustBeZero);
我的代码有 8 个线程,每个线程都试图从文件中读取数据,每个线程都有一个单独的文件句柄和自己的读取指针,我正在从一个 80K 块的 35GB 文件中读取数据。
有时此读取会因错误 0xc00000e8 (STATUS_INVALID_USER_BUFFER) 而失败,但我不明白为什么。
是什么原因导致了这个问题,我该如何解决?
我设法使用 GCHandle.Alloc
解决了问题
GCHandle gch = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
r = WdfWin32Native.ReadFile(handle, bytes, count, out numBytesRead, IntPtr.Zero);
}
finally
{
gch.Free();
}
声明了 ReadFile:
unsafe internal static extern int ReadFile(SafeFileHandle handle,
byte [] bytes, int numBytesToRead, out int numBytesRead, IntPtr mustBeZero);
我不确定为什么这样可以解决问题,但它似乎确实如此。
我正在编写一些代码来绕过 FileStream 中的缓冲从二进制文件中读取块,因为它在使用 LockFileEx 锁定文件区域时会导致问题。此代码与来自参考源的 FileStream 中的实现几乎相同。
private unsafe int ReadFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, out int hr)
{
int r = 0;
int numBytesRead = 0;
fixed (byte* p = bytes)
{
r = Native.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
}
ReadFile 是这样导入的:
unsafe internal static extern int ReadFile(SafeFileHandle handle, byte* bytes,
int numBytesToRead, out int numBytesRead, IntPtr mustBeZero);
我的代码有 8 个线程,每个线程都试图从文件中读取数据,每个线程都有一个单独的文件句柄和自己的读取指针,我正在从一个 80K 块的 35GB 文件中读取数据。 有时此读取会因错误 0xc00000e8 (STATUS_INVALID_USER_BUFFER) 而失败,但我不明白为什么。
是什么原因导致了这个问题,我该如何解决?
我设法使用 GCHandle.Alloc
解决了问题 GCHandle gch = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
r = WdfWin32Native.ReadFile(handle, bytes, count, out numBytesRead, IntPtr.Zero);
}
finally
{
gch.Free();
}
声明了 ReadFile:
unsafe internal static extern int ReadFile(SafeFileHandle handle,
byte [] bytes, int numBytesToRead, out int numBytesRead, IntPtr mustBeZero);
我不确定为什么这样可以解决问题,但它似乎确实如此。