在循环中如何判断按钮是否按下
在一个form中,有一个timer触发的事件,里面有一个循环,要执行的东西较多,每次按暂停都要等本次timer事件结束才能反应,实时性太差,我希望在循环里能够判断按钮是否按下,如果按下了,本次timer事件就结束。百度了很久,没有找到办法,向兄弟们求助,谢谢大家! --------------------编程问答-------------------- 在按钮的点击事件中停止timer不行吗? --------------------编程问答-------------------- 把timer写成新线程,点击button即将线程挂起。 --------------------编程问答-------------------- 简单点,你加个bool成员变量(在方法外定义)点下时置为false
timer中处理的时候判断一下
while(变量)
{
} --------------------编程问答--------------------
两位兄弟理念基本一致,我现在就是这么做的,这样必须等timer的这次触发结束才会执行按钮的消息,所以不行 --------------------编程问答--------------------
不是很熟悉,届时尝试一下,兄弟们有没有类似的代码呀 --------------------编程问答-------------------- lz是不是因为timer中某一方法执行起来比较耗时,然后导致timer停止后程序无法及时响应?那应该从这个方法入手,而不是将timer停止 --------------------编程问答--------------------
我需要让它慢一点,我使用了“ Thread.Sleep(300000);”,我希望在这个事件里能够获取“暂停”按钮是否按下,然后我就可以跳出循环了。 --------------------编程问答-------------------- namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Action<int> actionSetText;
private System.Threading.Thread thread;
Boolean pause = true;
public Form1()
{
InitializeComponent();
actionSetText = setText;
button1_Click(null, null);
}
private void button1_Click(object sender, EventArgs e)
{
pause = !pause;
this.timer1.Enabled = !pause;
if (pause)
{
button1.Text = "暂停";
}
else
{
button1.Text = "运行";
}
}
private void work()
{
for (int i=0; i < 1000; i++)
{
System.Threading.Thread.Sleep(10);//替换成你要进行的后台操作
this.Invoke(actionSetText, new Object[1] { i });
while (pause)
{
System.Threading.Thread.Sleep(100);
}
}
}
private void setText(int i)//替换成你要进行的前台操作
{
this.Text = i.ToString();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (thread != null)
{
if (thread.IsAlive)
{
return;
}
}
thread = new System.Threading.Thread(work);
thread.Start();
}
}
}
--------------------编程问答-------------------- 这个例子里涉及线程和委托.
基本思路是:
1.钟定时准备开启线程 thread 在后台工作,但前提是上一个操作已经完成了.
if (thread != null)
{
if (thread.IsAlive)
{
return;
}
}
这里判断上一个线程是否执行完.
2.线程thread 用于执行 work 方法
thread = new System.Threading.Thread(work);
因此你原来的大部分工作代码要放置在work方法中。
3.在work方法执行的最细粒度中(最内侧循环)放置死循环响应暂停
while (pause)
{
System.Threading.Thread.Sleep(100);
}
4.需要注意的是,虽然大部分代码移植到work 方法就可以了,但线程中的代码不可访问用户界面(将导致不一致性),因此如果你原来的代码在操作用户界面(比如我这里操作窗口标题),那么需要用到委托和在主线程运行委托的概念。
4.1.将前台操作代码放置在一个函数中,如:
private void setText(int i)
{
this.Text = i.ToString();
}
4.2.创建setText方法的委托用于在当前线程执行它
private Action<int> actionSetText;是一个委托,它代表setText方法:
actionSetText = setText;
Action<int> 是指带有一个int的参数的无返回值的方法,这要与被委托的setText方法一致。
(带有返回值的委托可以用Fun)
4.3.在work方法中,把涉及前台操作的代码用在当前线程调用委托的方法实现:
this.Invoke(actionSetText, new Object[1] { i });
new Object[1] { i }是参数集合,即setText的参数i。 --------------------编程问答-------------------- 谢谢楼上几位兄弟,我下午来测试一下,长知识了
补充:.NET技术 , C#