zoukankan      html  css  js  c++  java
  • 主线程和子线程的区别

    每个线程都有一个唯一标示符,来区分线程中的主次关系的说法。 

    线程唯一标示符:Thread.CurrentThread.ManagedThreadID;

    • UI界面和Main函数均为主线程
    • 被Thread包含的“方法体”或者“委托”均为子线程
    • 委托可以包含多个方法体,利用this.Invoke去执行。
    • 也可以定义多种方法体,放在Thread里面去执行。则此方法体均为子线程。注意如果要修改UI界面的显示。则需要使用this.Invoke,否则会报异常。
    • Main函数为主线程,id标示符与UI界面主线程相等

      看下面的测试代码注释吧。

     
    public delegate void dele();
        public partial class Form1 : Form
        {
            int idA;
            public dele getlab;
            public Form1()
            {
                InitializeComponent();
                idA  = Thread.CurrentThread.ManagedThreadId;//UI界面主线程
                /*
                 * Main函数为主线程,id标示符与UI界面主线程相同。
                 */
            }
    
            Thread thread;
            private void getbtu_Click(object sender, EventArgs e)//UI控件属于主线程
            {
                int idB = Thread.CurrentThread.ManagedThreadId;
                getlab = new dele(getLabel);//委托添加方法
                getlab += new dele(gg);//委托在叠加一个方法
                getlab += new dele(kk);//委托在叠加一个方法
                //
                thread = new Thread(new ThreadStart(delegate
                {
                    int idC = Thread.CurrentThread.ManagedThreadId;//Thread开辟一个子线程
                    //gg();//方法直接在thread里面调用均为子线程
                    //kk();//方法直接在thread里面调用均为子线程
                    getlab();//委托直接在thread里面调用,委托里面的方法为子线程
    
                    //以上因为都包含在thread里面
                    MessageBox.Show("显示完成");
    
                    //this.Invoke(getlab);
                    /*错误提示:主线程调用主线程当然会假死*/
                }));
                thread.IsBackground = true;
                thread.Start();
            }
            public void kk()//委托中的方法  委托方法三
            {
                int idR = Thread.CurrentThread.ManagedThreadId;
                this.Invoke((dele)(() =>//修改UI界面值则需要加this.Invoke
                {                 
                        label2.Text = "ABC";
                }));
            }
            public void gg()//委托中的方法  委托方法二
            {
                int idP = Thread.CurrentThread.ManagedThreadId;
                this.Invoke((dele)(() =>//修改UI界面值则需要加this.Invoke
                {
                        label3.Text = "QWE";
                }));
            }
            public void getLabel()//委托中的方法 委托方法一
            {       
                int idD = Thread.CurrentThread.ManagedThreadId;//子线程
    
                for (int i = 0; i <= 1000; i++)
                {
                    Thread.Sleep(10);
                    //this.Invoke为主线程,执行子线程的内容
                    this.Invoke((dele)(() =>
                    {
                        getlabel.Text = i.ToString();
                        int idE = Thread.CurrentThread.ManagedThreadId;//主线程
                        Console.WriteLine("线程idE:" + idE);
                    }));
                    Console.WriteLine(i);
                }
                MessageBox.Show("显示完成");
            }
    
            private void sleepbtu_Click(object sender, EventArgs e)//UI控件属于主线程
            {
                int idF = Thread.CurrentThread.ManagedThreadId;
                try
                {
                    if (thread.ThreadState != ThreadState.Suspended)
                    {
                        thread.Suspend();
                    }
                }
                catch (Exception r)
                {
                    MessageBox.Show(r.Message);
                }
            }
    
            private void setbtu_Click(object sender, EventArgs e)//UI控件属于主线程
            {
                int idG = Thread.CurrentThread.ManagedThreadId;
                try
                {
                    if (thread.ThreadState != ThreadState.Running)
                    {
                        thread.Resume();
                    }
                }
                catch (Exception r)
                {
                    MessageBox.Show(r.Message);
                }
            }
    
            public void getlabel_Click(object sender, EventArgs e)
            {
    
            }
        }
    
    

    总结: 
    UI界面和Main函数均为主线程,除了“不包含在Thread里面的程序”均可 视为主线程。包含在 Thread thread = new Thread(new ThreadStart(delegate{ 
    }));里面均视为子线程。

  • 相关阅读:
    机器不学习:如何处理数据中的「类别不平衡」?
    机器不学习:一种提升预测能力的方法-机器学习模型
    机器不学习:CNN 入门讲解1-什么是卷积
    机器不学习:浅析深度学习在实体识别和关系抽取中的应用
    机器不学习:用神经模块网络学习推理
    机器不学习:初识迁移学习
    机器不学习:一文彻底读懂智能对话系统
    跟随鼠标的div
    回到顶部的流畅滚动——scrollTop
    js学习小笔记
  • 原文地址:https://www.cnblogs.com/yanglang/p/9067282.html
Copyright © 2011-2022 走看看