当前位置:编程学习 > C#/ASP.NET >>

在循环中如何判断按钮是否按下

在一个form中,有一个timer触发的事件,里面有一个循环,要执行的东西较多,每次按暂停都要等本次timer事件结束才能反应,实时性太差,我希望在循环里能够判断按钮是否按下,如果按下了,本次timer事件就结束。百度了很久,没有找到办法,向兄弟们求助,谢谢大家! --------------------编程问答-------------------- 在按钮的点击事件中停止timer不行吗? --------------------编程问答-------------------- 把timer写成新线程,点击button即将线程挂起。 --------------------编程问答-------------------- 简单点,你加个bool成员变量(在方法外定义)
点下时置为false
timer中处理的时候判断一下
while(变量)
{
} --------------------编程问答--------------------
引用 1 楼 Change_L 的回复:
在按钮的点击事件中停止timer不行吗?



引用 3 楼 dongxinxi 的回复:
简单点,你加个bool成员变量(在方法外定义)
点下时置为false
timer中处理的时候判断一下
while(变量)
{
}

两位兄弟理念基本一致,我现在就是这么做的,这样必须等timer的这次触发结束才会执行按钮的消息,所以不行 --------------------编程问答--------------------
引用 2 楼 danding_ge 的回复:
把timer写成新线程,点击button即将线程挂起。

不是很熟悉,届时尝试一下,兄弟们有没有类似的代码呀 --------------------编程问答-------------------- lz是不是因为timer中某一方法执行起来比较耗时,然后导致timer停止后程序无法及时响应?那应该从这个方法入手,而不是将timer停止 --------------------编程问答--------------------
引用 6 楼 zhou23141622 的回复:
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#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,