当前位置: 首页 > 知识库问答 >
问题:

这种行为是由于清理垃圾时无法预测的时间吗?[副本]

百里诚
2023-03-14

当我更改列表中的选择时,对话框会更新,读取与列表中的项目相关联的文件。我使用下面代码中的using语句修复了该问题。

    private void ViewModel_SelectedNoteChanged(object sender, EventArgs e)
    {
        try
        {
            contentRichTextBox.Document.Blocks.Clear();

            if (VM.SelectedNote != null)
            {
                if (!string.IsNullOrEmpty(VM.SelectedNote.FileLocation))
                {
                    using (FileStream fileStream = new FileStream(VM.SelectedNote.FileLocation, FileMode.Open))
                    {

                        var contents = new TextRange(contentRichTextBox.Document.ContentStart, contentRichTextBox.Document.ContentEnd);
                        contents.Load(fileStream, DataFormats.Rtf);
                    }
                }
            }
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

如果我不使用上面的using语句,它的命中或失败。有时它从文件中读取内容并显示它们,否则会引发异常。

System.io.IOException:“进程无法访问文件”D:\EClone\bin\debug\netcoreApp3.1\3.rtf“,因为另一个进程正在使用该文件。”

共有1个答案

高豪
2023-03-14

这正是由于IDisposable和GC的使用不正确造成的。不使用使用

  • 打开文件(从而锁定它)并将引用存储在变量中
  • 函数退出,但文件仍被打开并锁定。
  • 如果GC运行之前,您将尝试再次打开文件--一切正常,因为在文件包装器的终结器中有一个关闭(和解锁)文件的代码。
  • 如果在GC运行之前尝试访问同一文件-将会出现异常。

如果使用,您将通过调用dispose来显式关闭和解锁文件(using将为您调用它)。dispose将立即关闭和解锁文件,而无需等待GC,因此使用using时,您的代码将始终按预期工作。

此外,由于您无法控制,当GC将运行时,没有使用的代码是不稳定的by design,因此即使它今天工作良好,明天也可能停止工作,原因是系统有更多的空闲内存(而且GC运行的频率不像今天那么高),或者是.NET更新(有一些GC更改/改进)等等。

因此,作为结论:如果您有实现IDisposable的东西,那么在不再需要该对象时(使用或手动使用),总是调用Dispose。只有在文档或指南中明确允许调用Dispose(例如,对于Task类)时,才可以省略调用Dispose

 类似资料:
  • 引用CLEAN.nsi的内容: ; 该脚本使用 HM VNISEdit 脚本编辑器向导产生 ; 安装程序初始定义常量 !define PRODUCT_NAME "Windows简易垃圾清理器" !define PRODUCT_VERSION "1.0" !define PRODUCT_PUBLISHER "似水年华" SetCompressor /final /SOLID lzma ; --

  • 这是一个内存数据安全问题。 java垃圾收集是否安全地清除垃圾数据? 显然,在一个数据块被垃圾收集后,我不能再检索它了,但黑客还能通过内存转储来检索数据吗?

  • 在我们的kafka broker设置中,GC平均需要20毫秒,但随机增加到1-2秒。极端情况持续9秒。这种情况的发生频率相当随机。平均每天发生15次。我尝试过使用GCEasy,但没有给出任何见解。我的内存使用率为20%,但进程仍然使用交换,尽管内存可用。感谢您对如何将其最小化的任何意见 JVM选择: GC日志:

  • 在这个问题的启发下,我写出了测试题: 本程序以普通大小写形式打印: 首先:我解释这种行为是JIT编译器的存在。“预热”后,每个线程的JIT编译器缓存值非字段。对吧? 第二:如果先对或不对,我如何验证这一点? 附注。-我知道打印-选项。 更新:enviroment:Windows 7 64bit,JDK 1.7.0_40-b43(热点)。

  • 问题内容: 我有一段代码可以在内存中加载很大的图像。所以打电话似乎是合理的事情 在加载图像之前。据我所知,它毫无问题。 昨天,我决定使用一个名为FindBugs的非常有用的软件来扫描您的代码并报告可能导致错误或通常不建议使用的策略的问题。问题是我提到的这段代码得到了报告。描述是这样的: …强迫垃圾收集;除了基准测试代码外,都非常可疑 并继续阐述: 代码显式调用垃圾回收。除了基准测试中的特定用途外,

  • 对于以前的光盘一般都是用批处理来达到安装完相应的软件而清理掉的效果! 但可以看出用 NSIS 同样也可以实现。 当然也可以参考集成光盘安装时产生的垃圾简易清理器(批处理) http://dreams8.com/viewthread.php?tid=789 其实批处理都能实现的,但用NSIS打包一下是不是更酷呢? 引用脚本的内容: ; 该脚本使用 HM VNISEdit 脚本编辑器向导产生 ;