为什么在StreamReader.Read周围使用using(){}允许之后删除文件?

Tan*_*eng 1 c# using streamreader winforms system.io.file

所以我正在为学校项目尝试Windows表单并继续遇到错误:

System.IO.IOException('进程无法访问文件'C:\ XXXX\YYYY.txt',因为它正由另一个进程使用.'

当试图File.Delete(path);通过button_click事件删除文件()时.

事实证明,当我改变以下方法时:

private void updateTxt(){
  String tempStore = "";
  iDLbl1.Text = "ID:" + id;//iDLbl1 is ID Label 1
  try
  {
      StreamReader Reader = new StreamReader(path);
      while (!Reader.EndOfStream)
        { tempStore += Reader.ReadLine() + "\n"; }
  }
  catch { noIDLbl.Visible = true; }
  rTxtBox.Text = tempStore;//rTxtBox is Rich Text Box
} 
Run Code Online (Sandbox Code Playgroud)

private void updateTxt(){
    String tempStore = "";
    iDLbl1.Text = "ID:" + id;//iDLbl1 is ID Label 1
    try
    {
        using(StreamReader Reader = new StreamReader(path))
        {
            while (!Reader.EndOfStream)
            { tempStore += Reader.ReadLine() + "\n"; }
        }

    }
    catch { noIDLbl.Visible = true; }
    rTxtBox.Text = tempStore;//rTxtBox is Rich Text Box
}
Run Code Online (Sandbox Code Playgroud)

异常停止弹出.虽然代码有效,但我根本不知道究竟是什么原因造成的......逻辑似乎没有为我点击,所以任何人都知道为什么会发生这种情况或者有更合理的解决方案?如果需要请求澄清,这是构造函数以防万一:

public FindID(String ID)
{
    id = ID;
    path = @"C:\XXXX\YYYY\"+ID+".txt";
    InitializeComponent();
    updateTxt();
}
Run Code Online (Sandbox Code Playgroud)

Stu*_*tLC 6

在你的第一种方法,因为你没有Close()荷兰国际集团和Dispose()荷兰国际集团的StreamReader,相关的文件句柄将保持,直到StreamReader被垃圾收集器,这可能是许多秒,甚至分钟后收集(请不要尝试控制或影响GC).

在第二种方法中,using作用域在作用域StreamReader的末尾(关闭}匹配using)处置(并关闭),这在使用任何实现的类时是正确的做法IDisposable.然后,它会释放文件的任何句柄,允许删除它.using块也具有try/finally块的保证,因此Dispose即使存在IO异常也会被调用:

using(StreamReader Reader = new StreamReader(path)) // try {StreamReader Reader = ...}
{
     ...
} <- equivalent to finally {Reader.Dispose();}
Run Code Online (Sandbox Code Playgroud)

但是,由于您似乎只想立即实现行分隔文本文件中的所有行,您可以使用File.ReadAllLines一步完成此操作- 即根本不需要StreamReader:

var tempStore = string.Join(Environment.NewLine, File.ReadAllLines(path));
Run Code Online (Sandbox Code Playgroud)