【2】Thread实例方法:生命周期管理的ThreadState

来源:互联网 发布:vb.net 多线程实例 编辑:程序博客网 时间:2024/04/27 23:36

1.clrThread这个名字来表示线程这个概念

本篇文章讲解Thread的实例方法:【idThreadState

 

 

2.如何管理Thread的生命周期

Start

Suspend

Resume

Interupt

Abort

(另外还有Join使用很多)

上面5种,在Thread的使用过程中非常多。

 

例子:实现生命周期中的方法

我们可以实现一个每隔一秒,在TextBox中追加数字的效果


点击开始时,每隔1s,追加数字,并加1

 

创建window项目,编辑界面,添加TextBox和5个按钮

 

 

        Thread thread = null;

        int index = 0;

1)开始事件:

        ///<summary>

        /// 开启线程

        /// </summary>

        /// <paramname="sender"></param>

        /// <paramname="e"></param>

        private void button1_Click(objectsender, EventArgs e)

        {

            thread = new Thread(newThreadStart(() =>

            {

                while (true)

                {

                    try

                    {

                        Thread.Sleep(1000);

                        textBox1.Invoke(newAction(() =>

                                    {

                                       textBox1.AppendText(string.Format("{0}", index++));

                                    }));

                    }

                    catch (Exception ex)

                    {

                       MessageBox.Show(string.Format("{0},{1}", ex.Message,index));

                        throw;

                    }

                }

            }));

            thread.Start();

        }

 

2)暂停事件:

        /// <summary>

        /// 暂停

        /// </summary>

        /// <paramname="sender"></param>

        /// <paramname="e"></param>

        private void button2_Click(objectsender, EventArgs e)

        {

            //在启动或者休眠期间可进行暂停

           if(thread.ThreadState==ThreadState.Running ||thread.ThreadState==ThreadState.WaitSleepJoin)

                thread.Suspend();//已经弃用了

        }

 

点击开始,然后再点击暂停,我们可以在此时使用windbg来查看thread的状态

 

打开windbg32位,File->Attachto a Process

可以看到有一个后台线程,BackgroundThread1,总共是3个线程


执行!clrstack查看CLR堆栈


可以点击下图中的State(第三个是主线程),可以看到状态信息。

显示信息

 退出windbg

3)恢复Resume:将挂起的线程重新启动

        /// <summary>

        /// 恢复挂起的线程

        /// </summary>

        /// <paramname="sender"></param>

        /// <paramname="e"></param>

        private void button3_Click(objectsender, EventArgs e)

        {

            if (thread.ThreadState ==ThreadState.Suspended)

            {

                thread.Resume();

            }

        }

 

 

 

4)中断Interrupt:用来中断处于WaitSleepJoin状态的线程。

就像

While(true){

Continue ….效果

}

的效果

 

但是,当你调用interrupt的时候,会抛出一个interrput的异常。

抛出异常后,while循环仍然继续执行。

所以,如果打印了1,2,3之后中断,那么打印的4大概需要4秒(2+2秒休眠时间)

5Abort

通过抛出异常的方式销毁一个线程,终止次线程。那么,线程后面的操作就不会再执行了。停止后,TextBox就停在3上了。


 

可以看出AbortInterrupt之间的区别

 

 

此时,使用windbg附加进程,加载sosclr,查看线程

可以看到此时的主线程抛出了AbortException

重新开启window程序,启动-》中止

如果将弹出框(正在中止线程)关闭,那么线程就关闭了

打开windbg附加进程,可以看到线程死了,并且主线程的OSID没了,说明已经销毁。

点击状态下的数字:

 

常用的方法:Join:

例子:

创建一个控制台程序:

    class Program

    {

        static void Main(string[] args)

        {

            Thread t = new Thread(newThreadStart(() =>

            {

                Thread.Sleep(1000);

               Console.WriteLine("子线程执行完毕");

            }));

            t.Start();

            t.Join();//调用线程等待子线程执行完之后才执行。。。【在此等待子线程执行完毕】

 

           Console.WriteLine("主线程执行完毕");

            Console.Read();

 

        }

    }

 

执行,t.Join(),那么主线程必须等待子线程t执行完毕后,才能继续向后执行。相当于阻塞主线程。

执行结果:

如果不加t.Join();那么主线程会先执行完毕。

将上述的休眠时间调长,使用windbg,查看这个睡眠的线程能否被中断:

可以看到,这是一个可中断的线程









原创粉丝点击