多线程开发(1):主线程,前台线程,后台线程,守护线程,子线程,托管线程的关系

1.主线程
当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(Main Thread),因为它是程序开始时就执行的,如果你需要再创建线程,那么创建的线程就是这个主线程的子线程。每个进程至少都有一个主线程,在Winform中,应该就是创建GUI的线程。主线程的重要性体现在两方面:1.是产生其他子线程的线程;2.通常它必须最后完成执行比如执行各种关闭动作。

 

2.前台线程,后台线程,托管线程,守护线程

CLR能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。 一个线程是前台线程还是后台线程可由它的IsBackground属性来决定。这个属性是可读又可写的。它的默认值为false,即意味着一个线程默认为前台线程。我们可以将它的IsBackground属性设置为true,从而使之成为一个后台线程。
后台线程又叫守护线程,它被CLR认为是程序执行中可做出牺牲的途径,即在任何时候都可能被忽略,因此,如果所有的前台线程终止,当应用程序域卸载时,所有的后台线程也会被自动终止。值得注意的是:前台线程和后台线程并不等同于主线程和工作线程,默认情况下,通过Thread.Start()方法创建的线程都自动成为前台线程。把线程的IsBackground属性设为 true就可以将线程配置为后台线程。

托管线程或者是后台线程,或者是前台线程。 后台线程不会使托管执行环境处于运行状态,除此之外,后台线程与前台线程是一样的。 一旦所有前台线程在托管进程(其中 .exe 文件是托管程序集)中被停止,系统将停止所有后台线程并关闭。

 

3.子线程

默认情况,在新开启一个子线程的时候,他是前台线程,只有,将线程的IsBackground属性设为true;他才是后台线程
当子线程是前台线程,则主线程结束并不影响其他线程的执行,只有所有前台线程都结束,程序结束
当子线程是后台线程,则主线程的结束,会导致子线程的强迫结束
(个人理解,这样设计的原因:因为后台线程一般做的都是需要花费大量时间的工作,如果不这样设计,主线程已经结束,而后台工作线程还在继续,第一有可能使程序陷入死循环,第二主线程已经结束,后台线程即时执行完成也已经没有什么实际的意义)

 

4.名词之间的关系总结

  托管线程包括前台线程和后台线程

  守护线程是后台线程

  主线程是一个前台线程,前台线程可以是多个的

  子线程是从属与主线程的,子线程可以是多个

5.DEMO:

    public partial class Form1 : Form
    {      
        public Form1()
        {
            j=1;
            InitializeComponent();
        }
        static int j;

        private void btnMultiThread_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(new ThreadStart(MultiMethod));//子线程默认是前台线程
            th.IsBackground = true;//将一个线程设置为后台线程,就可以保证前台线程关闭后,后台线程也会停止执行。
            th.Start();         
            //this.lbCounter.Text = j.ToString();
        }

        private void MultiMethod()
        {
            for (int i = 0; i < 99999999; i++)
            {
               
            }
            j=10000;//j是上下文中的变量,属于进程(static),所以是可以访问的。
            //this.lbCounter.Text =j.ToString();//控件是属于UI线程(主线程,前台线程),直接跨线程是访问不了的。
            MessageBox.Show("循环9999999次结束!");//MessageBox类是进程上下文环境中的资源,不属于Form1主线程(前台线程,UI线程)
            this.Invoke(new Action(() => { lbCounter.Text = j.ToString(); }));//跨线程需要使用主线程的Invoke方法
        }

        private void btnSingle_Click(object sender, EventArgs e)
        {
            MultiMethod();//UI线程是同步,会等待不少时间。
        }

        private void btnCloseUI_Click(object sender, EventArgs e)
        {
            this.Close();//前台线程(UI线程,主线程)关闭,后台线程会停止执行
        }
    }

 

6.参考资料

http://msdn.microsoft.com/zh-cn/library/h339syd0

http://npfeng900.blog.163.com/blog/static/14456108201092431813416/

http://blog.sina.com.cn/s/blog_4b3485000100pigr.html

http://blog.csdn.net/jasonvip_c/article/details/5718636

http://baike.baidu.com/link?url=iHKpEFeXOm3-za_4Uq0RRUlhanBFw063O0UAMCRb6VcF_3xaU-x9kQ-tQcUdDBnn

http://zhidao.baidu.com/link?url=HKDefTGtJmyAdl5WykvUM16fk0VvGT3GNxcWXVSparKjVSmRRJ4ZstO_ovD-pyQc9Iz6KoFLV2U5uLAiOwJH4q

http://blog.sina.com.cn/s/blog_729dcc220100orwc.html

posted @ 2013-10-19 23:31  翱翔之鹰  阅读(1106)  评论(0编辑  收藏  举报