C# DBreeze在mono中运行不正常

C# DBreeze在mono中运行不正常,c#,.net,linux,mono,fsync,C#,.net,Linux,Mono,Fsync,我提交这个问题有两个原因:我在使用Mono下运行的DBreeze数据库引擎时遇到困难,但我找到了一个解决方法,它可能会帮助其他人解决这个确切的问题(我将此方法作为一个答案发布),如果其他人知道更好的解决方案,我将感谢他们的帮助 问题是在Windows上工作正常,但在使用Mono的Linux上,在引擎初始化和第一次插入之后,它会引发以下异常: Unhandled Exception: DBreeze.Exceptions.DBreezeException: Getting table "@utt2

我提交这个问题有两个原因:我在使用
Mono
下运行的
DBreeze
数据库引擎时遇到困难,但我找到了一个解决方法,它可能会帮助其他人解决这个确切的问题(我将此方法作为一个答案发布),如果其他人知道更好的解决方案,我将感谢他们的帮助

问题是在Windows上工作正常,但在使用Mono的Linux上,在引擎初始化和第一次插入之后,它会引发以下异常:

Unhandled Exception: DBreeze.Exceptions.DBreezeException: Getting table "@utt2"
from the schema failed! ---> DBreeze.Exceptions.TableNotOperableException:
DBreeze.Scheme ---> DBreeze.Exceptions.DBreezeException: Rollback of the table
"DBreeze.Scheme" failed! ---> DBreeze.Exceptions.DBreezeException: Restore
rollback file "./DB/_DBreezeSchema" failed! --->
System.EntryPointNotFoundException: FlushFileBuffers
问题出在
DBreeze/Storage/FSR.cs文件中,因为它试图调用

    [System.Runtime.InteropServices.DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
    private static extern bool FlushFileBuffers(IntPtr hFile);
但这在Mono中不受支持


问题是:如何正确地刷新filebuffer/调用与kernel32.dll的
FlushFileBuffers()
等效的文件缓冲区,将缓冲区内容写入Mono下的磁盘?

我的解决方法如下:

由于此方法将数据从操作系统文件缓冲区同步到硬盘驱动器(或任何块设备),因此本机unix
fsync
方法也可以执行相同的操作

对我有效的解决方法是使用自定义函数替换上面的DllImport:

        // [System.Runtime.InteropServices.DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
        // private static extern bool FlushFileBuffers(IntPtr hFile);
        private static bool FlushFileBuffers(IntPtr handle)
        {
            return Mono.Unix.Native.Syscall.fsync(handle.ToInt32()) == 0 ? true : false;
        }
fsync
如果没有错误,则返回
0
;如果有错误,则必须将句柄从
IntPtr
转换为
int

编译期间,必须在命令行中添加参数
/r:Mono.Posix.dll
,才能访问
fsync
本机系统调用


我不完全确定这个技巧是否能完全按照原始代码中的预期工作,因为刷新缓冲区的级别取决于操作系统,所以请告诉我是否有更好/正确的解决方案来解决这个问题,或者我发现的这个解决方案是完全正确的。

对于.net40及更高版本,您可以使用函数

#if NET40
    public static void NET_Flush(FileStream mfs)
    {
        mfs.Flush(true);
    }
#else

    [System.Runtime.InteropServices.DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
    private static extern bool FlushFileBuffers(IntPtr hFile);

    public static void NET_Flush(FileStream mfs)
    {
        mfs.Flush();
        IntPtr handle = mfs.SafeFileHandle.DangerousGetHandle();

        if (!FlushFileBuffers(handle))
            throw new System.ComponentModel.Win32Exception();
    }
#endif

为了适应本网站的格式,请将此编辑为问题,并将答案添加为以下答案。这个问题不应该自己回答谢谢你的建议,我已经把它分开了。