停止长时间运行的事件

时间:2012-10-03 15:50:33

标签: c# events

我有一个Form3,由另一个Form1打开,当关闭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();
    }

}

5 个答案:

答案 0 :(得分:2)

你永远不会突破(真实)。你应该在IsDisposed为真时打破循环,将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();
    }

}

答案 1 :(得分:2)

你的基本方法存在缺陷。

首先,应该避免使用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已配置。设置tick事件以及间隔。 tick事件看起来与您的DoSomething方法类似;它将涉及从UI线程每10秒运行一些代码,同时保持UI响应。当表单关闭时,只需停止计时器,它就会停止触发这些事件。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

感谢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();
    }

}

答案 4 :(得分:0)

尝试在FormClosing事件中添加以下解释: System.Diagnostics.Process.GetCurrentProcess().Kill();

有点像这样:

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