为什么Form_FormClosing事件在c#.net中执行2次

问题描述:

我在C#.net中有一个windows窗体应用程序,我想通过X按钮关闭窗体时备份所以我在代码下面写下了这个动作。但是当我运行程序我注意到这个事件执行2次请帮我解决这个问题为什么Form_FormClosing事件在c#.net中执行2次

private void MenuFrm_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      // DialogResult dialogResult = MessageBox.Show("ایا مایل به گرفتن نسخه پشتیبان می باشید", "هشدار", MessageBoxButtons.YesNo); 
      // if (dialogResult == DialogResult.Yes && !closefrm) 
      try 
      { 
       DialogResult dialogResult = MessageBox.Show("آیا مایل به خروج از نرم افزار میباشید؟", "خروج", MessageBoxButtons.YesNo); 
       if (dialogResult == DialogResult.Yes) 
       { 
        SaveFileDialog f = new SaveFileDialog(); 
        f.InitialDirectory = "D:\\"; 
        f.Title = "HoghooghDastmozdBackup"; 
        if (Directory.Exists("E:\\MobtakeranSoftBackup\\")) 
        { 
         f.FileName = "E:\\MobtakeranSoftBackup\\" + getPersianDate() + ".BAK"; 
         f.FilterIndex = 1; 
         f.OverwritePrompt = true; 
         f.Filter = @"SQL Backup files (*.BAK) |*.BAK|All files(*.*) |*.*"; 
         SqlConnection sqlconn = new SqlConnection(DBsetting.Connstring); 
         SqlCommand sqlcmd = new SqlCommand("BACKUP DATABASE HoghooghDastmozd TO DISK [email protected]", sqlconn); 
         sqlcmd.Parameters.AddWithValue("@n", f.FileName); 
         sqlconn.Open(); 
         sqlcmd.ExecuteNonQuery(); 
         sqlconn.Close(); 
         Application.Exit(); 
        } 
        else 
        { 
         Directory.CreateDirectory("E:\\MobtakeranSoftBackup\\"); 
         f.FileName = "E:\\MobtakeranSoftBackup\\" + getPersianDate() + ".BAK"; 
         f.FilterIndex = 1; 
         f.OverwritePrompt = true; 
         f.Filter = @"SQL Backup files (*.BAK) |*.BAK|All files(*.*) |*.*"; 
         SqlConnection sqlconn = new SqlConnection(DBsetting.Connstring); 
         SqlCommand sqlcmd = new SqlCommand("BACKUP DATABASE HoghooghDastmozd TO DISK [email protected]", sqlconn); 
         sqlcmd.Parameters.AddWithValue("@n", f.FileName); 
         sqlconn.Open(); 
         sqlcmd.ExecuteNonQuery(); 
         sqlconn.Close(); 
         Application.Exit(); 
        } 
       } 
       else 
       { 
        e.Cancel = true; 
       } 

      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
       Application.Exit(); 
      } 


     } 
+0

请确保您没有连接两个事件处理程序 - 在项目中搜索“MenuFrm_FormClosing”。您可能还想检查FormClosingEventArgs的CloseReason,因为这在Windows关闭时也会触发。 – stuartd

你叫Application.Exit()。这是在表格完全关闭之前完成的......它仍然是开放的。因此,触发了一个新的操作,其中涉及第二个事件。当你能够处理第二个事件时,第一个事件已经完成,表单完全关闭,所以它停在那里(最终事件触发两次,而不是更多)。

您可以通过向类添加一个布尔值来调整它的默认值为false,检查它在方法顶部是否为false,并在方法结束时将其设置为true。但这只是修补真正的问题......你在form_closing事件中做得太多了。呼叫Application.Exit()属于Form_Closed,通常只会触发一次。


虽然我在这里,我想指出这样的代码:

sqlconn.Open(); 
sqlcmd.ExecuteNonQuery(); 
sqlconn.Close(); 

这是不良的做法。 .Close()呼叫SqlConnection对象应该总是finally块(最简单的方法是通过using块)。在这种情况下,你可能没问题,因为应用程序即将退出,但以这种方式执行查询并不是一个好习惯,而且如果在程序中的其他地方犯了同样的错误,这也让人怀疑。我也想知道为什么你在这里重复这么多的代码。整个部分可以简化为:

Directory.CreateDirectory("E:\\MobtakeranSoftBackup\\"); //it's good to just call this, even if the directory already exists. 
f.FileName = System.IO.Path.Combine(@"E:\MobtakeranSoftBackup", getPersianDate() + ".BAK"); 
f.FilterIndex = 1; 
f.OverwritePrompt = true; 
f.Filter = @"SQL Backup files (*.BAK) |*.BAK|All files(*.*) |*.*"; 
using (var sqlconn = new SqlConnection(DBsetting.Connstring)) 
using (var sqlcmd = new SqlCommand("BACKUP DATABASE HoghooghDastmozd TO DISK [email protected]", sqlconn)) 
{ 
    sqlcmd.Parameters.AddWithValue("@n", f.FileName); 
     sqlconn.Open(); 
     sqlcmd.ExecuteNonQuery(); 
} 
Application.Exit();     
+0

Joel你的代码没有正常工作,它像我的代码一样工作。它在关闭应用程序时运行了两倍的时间。 – ssss

+0

只有水平线上方的部分可以解决您的问题。其他人在代码中指出了一些明显不良的做法。 –