【问题标题】:Why Form_FormClosing event execute 2 times in c#.net为什么 Form_FormClosing 事件在 c#.net 中执行 2 次
【发布时间】:2017-08-08 15:20:12
【问题描述】:

我在 C#.net 中有一个 Windows 窗体应用程序,我想在通过 X 按钮关闭窗体时备份所以我写了下面的代码来执行此操作。但是当我运行程序时,我注意到此事件执行 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 =@n", 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 =@n", 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();
            }


        }

【问题讨论】:

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

标签: c# events backup formclosing


【解决方案1】:

你打电话给Application.Exit()。这是在表单完全关闭之前完成的……它仍然是打开的。因此,触发了新的Close 操作,其中涉及第二个Form_Closing 事件。当您能够处理第二个事件时,第一个事件已经完成并且表单已完全关闭,因此它会停在那里(您最终会触发该事件两次,而不是更多)。

您可以通过在类中添加一个布尔值(默认为 false)来对此进行调整,在方法的顶部检查它是否为 false,并在方法的末尾将其设置为 true。但这只是修补了真正的问题……您在 form_closure 事件中做的太多了。 Application.Exit() 调用属于 Form_Closed,通常只会触发一次。


在这里,我想指出这段代码:

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

这是不好的做法。 SqlConnection 对象的.Close() 调用应该始终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 =@n", sqlconn))
{
     sqlcmd.Parameters.AddWithValue("@n", f.FileName);
      sqlconn.Open();
      sqlcmd.ExecuteNonQuery();
}
Application.Exit();                  

【讨论】:

  • Joel 您的代码运行不佳。它像我的代码一样运行。它在关闭应用程序时运行双倍时间。
  • 只有水平线上方的部分解决了您的问题。剩下的就是指出代码中一些明显的不良做法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 2014-10-15
  • 2011-10-28
相关资源
最近更新 更多