【问题标题】:c# My codes keep running after closing the winformc#关闭winform后我的代码继续运行
【发布时间】:2021-08-11 20:09:40
【问题描述】:

我有很多表单,我在我的 Main form 上管理它们。我使用 ShowDialog() 打开其他表单,而我的一些表单涉及定时器操作,在关闭对话框后继续运行,我使用

this.Close();

用于关闭显示对话框,但它仍然在后面工作,然后在我的主窗体上显示 messagebox.show 。我的意思是它是否像它仍然处于活动状态但我关闭了对话框一样工作?

下面的代码只是其中之一,它与任务等待一起使用,而我的其他表单使用计时器运行,我也遇到了同样的问题。

private async void ıconButton4_Click(object sender, EventArgs e)
    {
        saniye = 0;


        if (hız <= 29)
        {
            MessageBox.Show("Başlamadan önce hızı da belirlemeliyiz", "Hız belirtilmedi", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        else
        {
            buttondurdur.Enabled = true;

            button1.Enabled = false;
            button2.Enabled = false;

            menuStrip1.Enabled = false;

            richTextBox1.Text = string.Empty;


            TextFormatFlags flags = TextFormatFlags.Top | TextFormatFlags.Left |
                                    TextFormatFlags.WordBreak | TextFormatFlags.NoPadding |
                                    TextFormatFlags.TextBoxControl;

            timer1.Enabled = true;


            foreach (var word in GetWords())
            {
                richTextBox1.Text += (word + ' ');
                kelimesayısı += 1;
                do
                {
                    await Task.Delay(hız);
                } while (_isPaused);



                Size textSize = TextRenderer.MeasureText(richTextBox1.Text, richTextBox1.Font, richTextBox1.Size, flags);


                if (textSize.Height >= (richTextBox1.Height - 40))
                {
                    richTextBox1.Clear();
                }


            }




            if (Saying.Length >= 150)
            {
                timer1.Stop();
                MessageBox.Show("Okuma hızınız dakikada " + (kelimesayısı * 60) / saniye + " kelime ");
                timer1.Enabled = false;
                richTextBox1.Clear();
                button1.Enabled = false;
                button2.Enabled = true;
                buttondurdur.Enabled = false;
                Saying = string.Empty;
                kelimesayısı = 0;

                menuStrip1.Enabled = true;
                saniye = 0;

            }
            else
            {
                MessageBox.Show("Seçilen metin çok kısa ", "Uyarı", MessageBoxButtons.OK, MessageBoxIcon.Error);
                timer1.Enabled = false;
                richTextBox1.Clear();                
                buttondurdur.Enabled = false;
                Saying = string.Empty;
                saniye = 0;
                kelimesayısı = 0;

                button1.Enabled = true;
                button2.Enabled = true;

                menuStrip1.Enabled = true;
            }
        }




    }

【问题讨论】:

  • 您知道吗,您可以在将控件拖放到表单后重命名它们~?您应该重命名它们,因为每个控件都称为controltypeN 的某些变体的代码真的很难理解。你能想象如果微软采取同样的策略,而不是 string.Lengthstring.Contains/string.StartsWith 你只是有 string.IntProperty1string.BoolReturningMethod1/string.BoolReturningMethod2,那么使用 C# 会有多难吗?
  • 您有问题吗?如果您希望计时器在关闭表单时停止工作,请在计时器上调用Stop,然后设置Enabled=false;
  • 我尝试使用 timer1.stop 然后 enabled=false 但它不起作用代码仍然在后面运行
  • 在 Visual Studio 中中断执行并找出正在运行的代码。如果您只是关闭一个表单,并不意味着它停止执行代码。例如,您在哪里退出 while (_isPaused) 循环?

标签: c# dialog


【解决方案1】:

您可能想试试this.Dispose();,而不是this.Close();。虽然这是一个更糟糕的解决方案,但在这种情况下它可能会更好。

【讨论】:

    【解决方案2】:

    这就是我在评论中的意思。

    我创建了一个简单的表单应用程序,在主表单中添加了一个按钮并将其作为按钮处理程序运行:

    private void button1_Click(object sender, EventArgs e)
    {
        using (var dlg = new TheDialog())
        {
            if (dlg.ShowDialog(this) == DialogResult.OK)
            {
                MessageBox.Show("OK");
            }
        }
    }
    

    然后我编写了TheDialog Form 类(构建的目的是使用ShowDialog 以非模态方式运行)。

    我添加了三个按钮,一个标记为“开始计时器”,另外两个是用于非模态表单的标准 OK 和 Cancel 按钮(将它们设置为表单的 Accept 和 Cancel 按钮)。我还在对话框的表单上放置了一个计时器,将其时间设置为 15 秒(15000 毫秒)。以下是按钮处理程序:

    private void StartTimerBtn_Click(object sender, EventArgs e)
    {
        if (timer1.Enabled)
        {
            timer1.Stop();
        }
        timer1.Start();
    }
    
    private void CancelBtn_Click(object sender, EventArgs e)
    {
        DialogResult = DialogResult.Cancel;
        Close();
    }
    
    private void OkBtn_Click(object sender, EventArgs e)
    {
        DialogResult = DialogResult.OK;
        Close();
    }
    

    我将 Timer 的 Tick 事件连接到:

    private void timer1_Tick(object sender, EventArgs e)
    {
        MessageBox.Show("Timer Expired");
        timer1.Stop();
    }
    

    所以,如果你调出表格,按“开始计时器”并计数到 15,会弹出一个消息框说“计时器已过期”

    最后,我连接了对话框的FormClosing 事件。这将在表单关闭之前被调用 - 无论是因为有人按下了右上角的 [x] 还是那个人按下了 OKCancel 按钮(或按下了 [ESC] 或 [Enter])。

    private void TheDialog_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (timer1.Enabled)
        {
            timer1.Stop();
        }
    }
    

    这样,无论发生什么,当对话框关闭时,计时器都会停止。

    对于它的价值,只调用Dispose 是一个非常糟糕的主意。访问已处置的对象绝不是一个好主意 - 您需要先停止它。当表单被释放时,您在设计器中添加到表单的控件也将被释放。

    还值得注意的是,这就是Minimal Reproduceable Example 的真正含义

    【讨论】:

      猜你喜欢
      • 2013-09-11
      • 1970-01-01
      • 2020-09-06
      • 2018-10-12
      • 1970-01-01
      • 2019-08-05
      • 1970-01-01
      • 2019-07-18
      • 2021-02-26
      相关资源
      最近更新 更多