首页 > 解决方案 > Visual C# When are Close() and Dispose() Needed?

问题描述

I am new to Visual C# and don't understand when I need to use the Close() and Dispose() methods on FileStream and StreamReader objects. In the code snippet below, I open a file, read the first line, and validate that it is what is expected. Do I need all of the Close() and Dispose() calls shown? If not, when are they needed? Thank you!

        FileStream fs = null;
        StreamReader sr = null;

        try
        {
            fs = new FileStream(txtMstrFile.Text, FileMode.Open, FileAccess.Read);
            using (sr = new StreamReader(fs))
            {
                if (String.IsNullOrEmpty(sLine = sr.ReadLine()))
                {
                    MessageBox.Show(Path.GetFileName(txtMstrFile.Text) + " is an empty file.", "Empty Master File", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    sr.Close();
                    fs.Close();
                    fs.Dispose();
                    return;
                }
                if(!String.Equals(sLine, "Master File"))
                {
                    MessageBox.Show(Path.GetFileName(txtMstrFile.Text) + " has an invalid format.", "Master File is Invalid", MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                    sr.Close();
                    fs.Close();
                    fs.Dispose();
                    return;
                }
        // Code to process sLine here
                sr.Close();
            }
            fs.Close();
            fs.Dispose();
        }
        catch (IOException ex)
        {
            MessageBox.Show(Path.GetFileName(txtMstrFile.Text) + "\r\n" + ex.ToString(), "File Access Error", MessageBoxButtons.OK,
                MessageBoxIcon.Error);
            sr.Close();
            fs.Close();
            fs.Dispose();
            return;
        }
        sr.Close();
        fs.Close();
        fs.Dispose();

标签: c#file-iodispose

解决方案


典型代码中明确 Dispose()Close()罕见的建议:using将为您完成:

   try {
     using (var sr = new StreamReader(new FileStream(txtMstrFile.Text, 
                                                     FileMode.Open, 
                                                     FileAccess.Read))) {
       string sLine = sr.ReadLine(); 

       if (String.IsNullOrEmpty(sLine)) {
         MessageBox.Show($"{Path.GetFileName(txtMstrFile.Text)} is an empty file.", 
                          "Empty Master File", 
                           MessageBoxButtons.OK,
                           MessageBoxIcon.Information);

         return;
       }
     
       if (!String.Equals(sLine, "Master File")) {
         MessageBox.Show($"{Path.GetFileName(txtMstrFile.Text)} has an invalid format.", 
                          "Empty Master File", 
                           MessageBoxButtons.OK,
                           MessageBoxIcon.Information);

         return;
       }  
     }  
   }
   catch (IOException ex) {
     MessageBox.Show($"{Path.GetFileName(txtMstrFile.Text)}\r\n{ex}", 
                      "File Access Error", 
                       MessageBoxButtons.OK,
                       MessageBoxIcon.Error);

     return;
   }   

请不要在创建消息时连接字符串,字符串插值$" ... "通常更具可读性

编辑:您可以完全摆脱 Streams 和StreamReaders:

   try {
     // That's enough to read the 1st file's line
     string sLine = File.ReadLines(txtMstrFile.Text).First();

     if (String.IsNullOrEmpty(sLine)) {
       MessageBox.Show($"{Path.GetFileName(txtMstrFile.Text)} is an empty file.", 
                        "Empty Master File", 
                         MessageBoxButtons.OK,
                         MessageBoxIcon.Information);

       return;
     }
     
     if (!String.Equals(sLine, "Master File")) {
       MessageBox.Show($"{Path.GetFileName(txtMstrFile.Text)} has an invalid format.", 
                        "Empty Master File", 
                         MessageBoxButtons.OK,
                         MessageBoxIcon.Information);

       return;
     }
   }
   catch (IOException ex) {
     MessageBox.Show($"{Path.GetFileName(txtMstrFile.Text)}\r\n{ex}", 
                      "File Access Error", 
                       MessageBoxButtons.OK,
                       MessageBoxIcon.Error);

     return;
   } 

推荐阅读