繁体   English   中英

停止长时间运行的事件

[英]Stop long running events

我有一个由另一个表单 Form1 打开的以下表单 Form3,当关闭 Form1 时,它会重新打开。

问题是当我关闭 Form3 时,DoSomething 在表单关闭后继续运行。

我知道我可以将 DoSomething 变成一个线程并设置 IsBackground = true 但还有另一种方法可以在表单关闭时停止所有进程。

此代码只是示例,用于说明。

   public partial class Form3 : Form
    {

    public Form3()
    {
        InitializeComponent();
    }
    private void DoSomething()
    {
        int i = 0;
        while(true)
        {
            if (!this.IsDisposed)
            {
                Application.DoEvents();
                i++;
                Thread.Sleep(10);
                label1.Text = i.ToString();
                dataGridView1.Rows.Add();
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void Form3_FormClosed(object sender, FormClosedEventArgs e)
    {
        this.Dispose();
        Form1.Default.Show();
    }

}

你永远不会突破 while(true)。 您应该在 IsDisposed 为 true 时中断循环,将 while 循环更改为 while(!IsDisposed),或者存储使用确定何时中断循环的类级别变量。

我可能会选择后者,因为它给了你更多的控制权。

public partial class Form3 : Form
{
    volatile bool clDoSomething;

    public Form3()
    {
        InitializeComponent();
    }
    private void DoSomething()
    {
        int i = 0;
        clDoSomething = true;
        while(clDoSomething)
        {
            Application.DoEvents();
            ++i;
            Thread.Sleep(10);
            label1.Text = i.ToString();
            dataGridView1.Rows.Add();
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void Form3_FormClosed(object sender, FormClosedEventArgs e)
    {
        clDoSomething = false;
        Form1.Default.Show();
    }

}

你的基本方法有缺陷。

首先,应避免使用Application.DoEvents,除非您确定确实需要它并且正确使用它。 您在这里不需要它,并且您没有正确使用它。

你真正需要的是一个Timer

private Timer timer = new Timer();
private int count = 0;
public Form3()
{
    InitializeComponent();

    timer.Tick += timer_Tick;
    timer.Interval = 10;

    //when the form is closed stop the timer.
    FormClosed += (_, args) => timer.Stop();
}

private void button1_Click(object sender, EventArgs e)
{
    count = 0;
    timer.Start();
}

private void timer_Tick(object sender, EventArgs e)
{
    count++;
    label1.Text = count.ToString();
    dataGridView1.Rows.Add();
}

创建Form时,配置Timer 滴答事件与间隔一起设置。 滴答事件看起来类似于你的DoSomething方法; 它将涉及每 10 秒从 UI 线程运行一些代码,同时保持 UI 响应。 当表单关闭时,只需停止计时器,它将停止触发这些事件。

另请注意,在此示例中,多次按下按钮只会重置计时器和计数,它最终不会创建两个循环,每个循环每 10 毫秒触发一次。

根据需要覆盖this.Dispose()this.Close()并手动this.Close() DoSomething() 。

感谢 cdhowie 的建议和所有其他人的投入。 将 DoEvents 修剪到最后并添加 IsDipsosed 解决了我的问题。

public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
    }
    private void DoSomething()
    {
        int i = 0;
        while ((true) && !this.IsDisposed)
        {
                i++;
                Thread.Sleep(10);
                label1.Text = i.ToString();
                dataGridView1.Rows.Add();
                Application.DoEvents();
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoSomething();
    }

    private void Form3_FormClosed(object sender, FormClosedEventArgs e)
    {
        Form1.Default.Show();
    }

}

尝试在 FormClosing 事件中添加此指令: System.Diagnostics.Process.GetCurrentProcess().Kill();

有点像这样:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    System.Diagnostics.Process.GetCurrentProcess().Kill();
}

暂无
暂无

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

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