简体   繁体   English

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

[英]Why Form_FormClosing event execute 2 times in c#.net

I have a windows form application in C#.net and I want to backUp while closing the form by X button So I Wroted below code to do this action .but when I run the program I noticed that this event execute 2 times Please Help me to solve this problem 我在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();
            }


        }

You're calling Application.Exit() . 您正在调用Application.Exit() This is done before the form has fully closed... it's still open. 这是在表单完全关闭之前完成的……它仍然处于打开状态。 Thus, a new Close operation is triggered, which involves a second Form_Closing event. 因此,将触发一个新的Close操作,该操作涉及第二个Form_Closing事件。 By the time you are able to process the second event, the first has finished and form is fully closed, and so it stops there (you end up with the event firing exactly twice, and not more). 到您能够处理第二个事件时,第一个事件已经完成并且窗体已完全关闭,因此它在那里停止了(您最终将事件触发两次,而不会触发更多次)。

You can adjust for this by adding a boolean to the class the defaults to false, check that it's false at the top of the method, and set it true at the end of the method. 您可以通过以下方法进行调整:在该类中添加一个默认为false的布尔值,在方法顶部检查其为false,然后在方法末尾将其设置为true。 But that's just patching over the real problem... you're doing too much in the form_closing event. 但是,这只是解决实际问题的方法……您在form_closing事件中做得太多。 The Application.Exit() call belongs in Form_Closed , which would typically only fire once. Application.Exit()调用属于Form_Closed ,通常只触发一次。


While I'm here, I want to point out this code: 当我在这里时,我想指出以下代码:

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

This is poor practice. 这是不好的做法。 The .Close() call for an SqlConnection object should always be in a finally block (the easiest way to accomplish that is via a using block). SqlConnection对象的.Close()调用应始终位于finally块中(最简单的方法是通过using块)。 In this case you're probably okay, because the application is about to quit anyway, but it's just not a good habit to execute queries this way, and it make one wonder if the same mistake is made elsewhere in the program. 在这种情况下,您可能会没事的,因为应用程序无论如何都将要退出,但是以这种方式执行查询并不是一个好习惯,这让人怀疑是否在程序的其他地方也犯了同样的错误。 I also wonder why you're repeating so much code here. 我也想知道您为什么在这里重复这么多代码。 That whole section can be reduced to this: 整个部分可以简化为:

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();                  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM