• 多线程开发(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

  • 相关阅读:
    JS判断浏览器
    【JS】时间不足10位补0方案
    【js学习小计】
    【Tangram】 通过监听进行事件触发
    JavaScript CSS Style属性对照表
    Resolve and Remove "BAD PASSWORD: It is Based on a Dictionary Word "in Linux
    [C++]关键字explicit
    [转]CentOS设置程序开机自启动的方法
    SqlServerCLR聚合函数:分组连接字符串
    vmware centos 虚拟机复制
  • 原文地址:https://www.cnblogs.com/youchun/p/3378618.html
Copyright © 2020-2023  润新知