窗体中启动多线程t,执行方法method,方法中满足某个条件后,线程自己暂停;当用户点击按钮后,继续执行线程。注意是继续执行线程,不是另外启动线程。代码如下:    public partial class Form1 : Form
    {        Thread t;
        public delegate void delegateM(int i);
        delegateM dm;        public Form1()
        {
            InitializeComponent();
        }        private void Form1_Load(object sender, EventArgs e)
        {
            dm = m;
            t = new Thread(Method);
            t.Start();
        }        void Method()
        {
            try
            {
                int i;
            cnt: i = 0;
                while (i < 300)
                {
                    Thread.Sleep(10);
                    i++;
                    this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
                    Application.DoEvents();
                }
                Thread.Sleep(-1);//线程暂时停止
                goto cnt;
            }
            catch
            { }
        }        void m(int i)
        {
            this.Text = i.ToString();
        }        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                t.Resume();//继续执行线程
            }
            catch
            { }
        }
    }调试发现,上述代码达不到预期目的。应该怎么修改呢?谢谢!

解决方案 »

  1.   

    用Thread的Suspend()方法吧,但你还得实时判断条件是否满足啊,这是个问题
      

  2.   

    怎么才能在线程方法Method里面Suspend呢?
      

  3.   


    private EventWaitHandle _EventWaitHandle;
    _EventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
                    _Thread = new Thread(Thread_Function);
    private void Thread_Function()
            {
                DataBuf protocolData;            protocolData = new DataBuf(_BufSize);            while (true)
                {                
                    _EventWaitHandle.WaitOne();//在此处阻塞线程                try
                    {
                        while (!_DataReceiveCycle.IsEmpty())
                        {
                            //                        }
                        }
                    }
                    catch (Exception ex)
                    {
                        Prj.Log.Add(MethodResultHelper.BuildExceptionMsg(ex.Message));
                    }
                }
            }
    _EventWaitHandle.Set(); //唤醒线程
      

  4.   

    这个应该不难吧.线程本身就有挂起的方法
    你也可以用各种锁,AutoResetEvent,ManualResetEvent都可以啊
      

  5.   

    1. Suspend 方法已经被废弃
    2. 所谓的等待,通常的做法就是轮空。
       要把Thread的工作切碎,划分成细粒度的执行单元,如果标志为挂起的话,就是什么也不做
       否则执行一个细粒度的工作
      

  6.   

    为了节约CPU,我希望让线程暂时停止,而不是做一些空的运转。
    Suspend方法已经“过时”了,那么微软推荐什么方法呢?
      

  7.   

    谢谢!sleep之后,让线程继续运行,用什么方法?
      

  8.   

    重新修改你的“设计”吧。不要弄一个无休止的线程。可以类似这样:    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void Form1_Load(object sender, EventArgs e)
            {
                tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed);
                tmr.Start();
            }        void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                i++;
                if (i >= 300)
                    i = 0;
                this.BeginInvoke(new Action(() => { m(i); }));
            }        int i;
            System.Timers.Timer tmr = new System.Timers.Timer(10);        void m(int i)
            {
                this.Text = i.ToString();
            }        private void button1_Click(object sender, EventArgs e)
            {
                tmr.Enabled = !tmr.Enabled;
            }
        }
      

  9.   

    轮空是你所说的空的运转
    轮空的意思是,线程主动放弃他应得的时间片,直到他得到了足够的资源(或达到了某些条件)另外你那个DoEvents不是用在主线程上,没有任何意义        private void MainForm_Load(object sender, EventArgs e)
            {
                new Thread(method).Start();
            }
            private AutoResetEvent threadEvent = new AutoResetEvent(false);
            private void button1_Click(object sender, EventArgs e)
            {
                threadEvent.Set();
            }
            void Method()
            {
                try
                {
                    int i;
                cnt: i = 0;
                    while (i < 300)
                    {
                        Thread.Sleep(10);
                        i++;
                        this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
                    }
                    threadEvent.WaitOne();
                    goto cnt;
                }
                catch
                { }
            }
        }
      

  10.   

    回11楼:
    “另外你那个DoEvents不是用在主线程上,没有任何意义”,是吗?能具体说下吗?我理解DOEvents就是让其它线程处理消息,为什么只是用于主线程中呢?谢谢
    线程重启的问题基本清楚了,应该就是你和3、4楼所说的,明天我再仔细看下MSDN的说法
      

  11.   

    DoEvents的作用是处理消息队列中积累的消息,只有在主线程忙的时候才需要调用你的method是跑在子线程上,并没有导致主线程忙
      

  12.   

    所谓的暂停,再继续 说白了就是一个flag// 按钮控制全局标志suspend 为true还是false
    private bool suspend = false;...
    int i = 0;
    while (i < 300)
    {
           if (!suspend)
           {
              i++;
              this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
           }
           Thread.Sleep(100); //就算没有暂停也适当等待,否则窗体无响应,直接显示300
           // Application.DoEvents(); 没用的语句
    }
    // 后面的goto也没啥用。当suspend=true时,while里就只执行Thread.Sleep
      

  13.   

    9楼程序不一定是lz想要得。如果lz想要得是线程执行到某个位置,等待一个信号或某个事件在继续执行的话,用autoresetevent,manualresetevent。 Monitor.wait
    等都可以。
    AutoResetEvent ev = new AutoResetEvent (false);
    public void Do()
    {
         //do sth;
         ev.waitone();//大小写自己调
         // do sth;
    }button-click()
    {
       ev.set();
    }
      

  14.   

    另受教了,还真不知道c#中有goto呢
      

  15.   

    呵呵,其实我也不知道,只是对FORTRAN、PASCAL这些语言很熟悉,习惯goto过去
      

  16.   

    用AutoResetEvent或者ManualResetEvent都可以,需要using System.Threading;public partial class Form1 : Form
        {        Thread t;
            public delegate void delegateM(int i);
            delegateM dm;        AutoResetEvent are;        public Form1()
            {
                InitializeComponent();
            }        private void Form1_Load(object sender, EventArgs e)
            {
                are = new AutoResetEvent(false);            dm = m;
                t = new Thread(Method);
                t.Start();
            }        void Method()
            {
                try
                {
                    int i;
                cnt: i = 0;
                    while (i < 300)
                    {
                        Thread.Sleep(10);
                        i++;
                        this.Invoke(dm, new object[] { i });//跨线程刷新窗体标题
                        Application.DoEvents();
                    }
                    are.WaitOne();//线程暂时停止
                    goto cnt;
                }
                catch
                { }
            }        void m(int i)
            {
                this.Text = i.ToString();
            }        private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    are.Set();//继续执行线程
                }
                catch
                { }
            }
        }
      

  17.   

    我的想法就是定义一个public的bool值,比如:IsRun=true;  然后  线程sleep多少秒后  判断IsRun是否允许运行 如果不允许 再次休眠....