【问题标题】:Can't delete file for MemoryMappedFile无法删除 MemoryMappedFile 的文件
【发布时间】:2011-07-12 07:38:54
【问题描述】:

以下代码抛出此异常:

“进程无法访问文件 '\filename',因为它正被另一个进程使用。”

很公平,但是关闭阅读器和/或 mmf 以便删除文件的正确方法是什么?我认为 MemoryMappedFile 会有一个 close() 方法或类似的方法,但它没有。

任何帮助将不胜感激。谢谢。

mmf = MemoryMappedFile.CreateFromFile(filename,
      System.IO.FileMode.OpenOrCreate,
      "myMap" + fileNo.ToString(),
      fileSize);

reader = mmf.CreateViewAccessor(0, accessorSize);

<do stuff>

File.Delete(filename);

编辑:

看起来只有在析构函数中我遇到了这个问题。当在其他地方调用 dispose() 时,它工作正常,但是当我执行以下操作时,它会引发异常。 Reader 和 mmf 显然是该类的成员。进入构造函数后,文件访问是否隐含发生?

~Class()
{
    try
    {
        if (File.Exists(filename))
        {
            reader.Dispose();
            mmf.Dispose();
            File.Delete(filename);
        }
    }
    catch (Exception e)
    {
    }
}

【问题讨论】:

  • 你不应该尝试在终结器中释放(或访问)其他对象,因为该对象可能已经被 GCed。
  • 但是析构函数的意义不在于能够在对象超出范围之前对其进行清理吗?不过,它认为这没有实际意义,因为我在代码的其他地方也遇到了这个问题。这不仅仅是析构函数的问题。
  • 终结器的重点是清理非托管资源; reader 和 mmf 是托管对象。
  • 确实,终结器(.net 没有析构函数)是一个单独的问题,我只是想指出它。而且我真希望 MS 没有在 C# 中为终结器使用 C++ 析构函数语法,这可能会防止人们将其视为 C++ 析构函数的一些错误。

标签: c# file memory-mapped-files


【解决方案1】:

如果可能,您应该使用using 构造:

using (var mmf = MemoryMappedFile.CreateFromFile(filename,
                   System.IO.FileMode.OpenOrCreate,
                   "myMap" + fileNo.ToString(), fileSize))
{
    using (reader = mmf.CreateViewAccessor(0, accessorSize))
    {  
       ... <do stuff> ...
    }
}

File.Delete(filename);

否则在readermmf 对象上调用Dispose(),但是using 将确保在&lt;do stuff&gt; 中引发异常时清理它。

【讨论】:

    【解决方案2】:

    在删除文件之前,您必须处理映射:

    reader.Dispose();
    mmf.Dispose();
    File.Delete(filename);
    

    【讨论】:

    • 谢谢。所以我认为我混淆了这个问题。我实际上已经尝试过上面的方法并且它没有用,但是在移动东西之后我发现它只在类析构函数中不起作用(即抛出异常)。你知道为什么它不能在析构函数中工作,而是在代码的其他地方工作吗?
    • 我收回了。它在析构函数以外的地方遇到问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 2011-11-03
    • 2014-02-07
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多