• 主线程和子线程的区别


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

    线程唯一标示符: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{ 
    }));里面均视为子线程。

  • 相关阅读:
    返回一个整数数组中子数组的最大值
    软工概论第二周个人项目四则运算二(改进)
    构建之法阅读笔记01
    单例模式
    .net基础加强
    使用jquery easy ui
    抽象工厂类
    System.Linq.Expressions.Expression
    创建上下文对象
    DBSesson
  • 原文地址:https://www.cnblogs.com/yanglang/p/9067282.html
Copyright © 2020-2023  润新知