在一个form中,有一个timer触发的事件,里面有一个循环,要执行的东西较多,每次按暂停都要等本次timer事件结束才能反应,实时性太差,我希望在循环里能够判断按钮是否按下,如果按下了,本次timer事件就结束。百度了很久,没有找到办法,向兄弟们求助,谢谢大家!

解决方案 »

  1.   

    在按钮的点击事件中停止timer不行吗?
      

  2.   

    把timer写成新线程,点击button即将线程挂起。
      

  3.   

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

  4.   

    两位兄弟理念基本一致,我现在就是这么做的,这样必须等timer的这次触发结束才会执行按钮的消息,所以不行
      

  5.   

    lz是不是因为timer中某一方法执行起来比较耗时,然后导致timer停止后程序无法及时响应?那应该从这个方法入手,而不是将timer停止
      

  6.   

    我需要让它慢一点,我使用了“ Thread.Sleep(300000);”,我希望在这个事件里能够获取“暂停”按钮是否按下,然后我就可以跳出循环了。
      

  7.   

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

  8.   

    这个例子里涉及线程和委托.
    基本思路是:
    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。