【问题标题】:DBreeze not running properly in monoDBreeze 在单声道中无法正常运行
【发布时间】:2018-08-26 05:15:15
【问题描述】:

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

问题是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 中不受支持。

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

【问题讨论】:

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

标签: c# .net linux mono fsync


【解决方案1】:

我的解决方法如下:

由于此方法会将数据从 OS 文件缓冲区同步到硬盘驱动器(或任何块设备),本机 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,如果有错误返回-1,句柄必须从IntPtr转换为int

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

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

【讨论】:

    【解决方案2】:

    对于 .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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 1970-01-01
      • 2012-01-30
      • 2015-11-10
      • 1970-01-01
      • 2020-08-07
      相关资源
      最近更新 更多