我有一个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();
}
}
答案 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();
}