C#线程基础(线程启动和停止)

2024-01-01 11:26:23

目录

一、关于线程

二、示例?

三、生成效果


一、关于线程

????????在使用多线程前要先引用命名空间System.Threading,引用命名空间后就可以在需要的地方方便地创建并使用线程。

????????创建线程对象的构造方法中使用了ThreadStart()委托,当线程开始执行时,将会执行委托中定义的方法。通过IsBackground属性设置线程为后台线程,调用线程对象的Start方法启动线程,开始执行。CancellationToken方法终止线程。

?????????创建的线程分为前台线程和后台线程,通过线程对象的IsBackground属性可以设置线程为前台线程或后台线程。前台线程与后台线程的区别是,后台线程不会使托管程序处于运行状态。也就是说,如果进程停止所有前台线程,那么系统会认为此进程处于非运行状态,将会停止所有后台线程并关闭。

????????适当地使用线程,可以增加程序的运行效率,使程序运行更加流畅,但是线程间的同步问题也显得尤为重要,可以使用线程锁或监视器有效地处理线程同步问题。

二、示例?

// 线程技术
// 使用随机对象产生一个1~100之间的整数,单击“开始”时,动态生成100个按钮并开始计时;
// 单击事件:按钮上的数字<随机数,那么被单击的按钮变为红色,并显示字符串“小”;
// 单击事件:按钮上的数字>随机数,那么被单击的按钮变为红色,并显示字符串“大”;
// 单击事件:按钮上的数字=随机数就会弹出消息框,提示已经猜对了数字,并显示用时及猜测次数。
namespace _033
{
    public partial class Form1 : Form
    {
        private Button? button1;
        private Label? label1;
        private Label? label2;
        private Label? label3;
        private Label? label4;
        Thread? thread_1;                    //定义线程
        readonly Random random_num = new();  //定义随机数对象
        int Temp_int_num;                    //定义变量用于存放存机数

        public Form1()
        {
            InitializeComponent();
            Load += Form1_Load;
        }
        private void Form1_Load(object? sender, EventArgs e)
        {
            // 
            // button1
            // 
            button1 = new Button
            {
                Location = new Point(30, 22),
                Name = "button1",
                Size = new Size(75, 23),
                TabIndex = 0,
                Text = "开始",
                UseVisualStyleBackColor = true
            };
            button1.Click += Button1_Click;
            // 
            // label1
            // 
            label1 = new Label
            {
                AutoSize = true,
                Location = new Point(206, 28),
                Name = "label1",
                Size = new Size(44, 17),
                TabIndex = 1,
                Text = "计时:"
            };
            // 
            // label2
            // 
            label2 = new Label
            {
                AutoSize = true,
                Location = new Point(256, 28),
                Name = "label2",
                Size = new Size(0, 17),
                TabIndex = 2
            };
            // 
            // label3
            // 
            label3 = new Label
            {
                AutoSize = true,
                Location = new Point(305, 28),
                Name = "label3",
                Size = new Size(20, 17),
                TabIndex = 3,
                Text = "秒"
            };
            // 
            // label4
            // 
            label4 = new Label
            {
                AutoSize = true,
                Location = new Point(115, 28),
                Name = "label4",
                Size = new Size(43, 17),
                TabIndex = 4,
                Text = ""
            };
            // 
            // Form1
            // 
            AutoScaleDimensions = new SizeF(7F, 17F);
            AutoScaleMode = AutoScaleMode.Font;
            ClientSize = new Size(379, 426);
            Controls.Add(label4);
            Controls.Add(label3);
            Controls.Add(label2);
            Controls.Add(label1);
            Controls.Add(button1);
            Name = "Form1";
            StartPosition = FormStartPosition.CenterScreen;
            Text = "猜数字";
            FormClosed += Form1_FormClosed;
        }

        private void Button1_Click(object? sender, EventArgs e)
        {
            RemoveControl();               //清空所有无用对象
            int bt_int_x = 10;             //X坐标初始值为10
            int bt_int_y = 60;             //Y坐标初始值为60
            for (int i = 0; i < 100; i++)  //添加100个按钮
            {
                Button bt = new()
                {
                    Text = (i + 1).ToString(),  //设置button按钮的文本值
                    Name = (i + 1).ToString(),  //设置button按钮的Name属性
                    Width = 35, 
                    Height = 35,   
                    Location = new Point(bt_int_x, bt_int_y)//设置button按钮的位置
                };
                bt.Click += new EventHandler(Bt_Click);     //定义button按钮的事件
                bt_int_x += 36;                             //设置下一个按钮的位置
                if ((i + 1) % 10 == 0)                      //每10个按钮就换行
                {
                    bt_int_x = 10;      //换行后重新设置X坐标
                    bt_int_y += 36;   //换行后重新设置Y坐标
                }
                Controls.Add(bt);   //将button按钮放入窗体控件集合中
            }
            thread_1 = new Thread(delegate ()       //新建一条线程使用匿名方法
                {
                    int P_int_count = 0;            //初始化计数器
                    while (true)                    //开始无限循环
                    {
                        P_int_count = ++P_int_count > 100000000 ? 0 : P_int_count;  //计数器累加
                        Invoke(                     //将代码交给主线程执行
                            (MethodInvoker)delegate //使用匿名方法
                            {
                                label2!.Text = P_int_count.ToString(); //窗体中显示计数
                            });
                        Thread.Sleep(1000);    //线程睡眠1秒
                    }
                })
            {
                IsBackground = true            //设置线程为后台线程
            };
            thread_1.Start();                  //开始执行线程
            Temp_int_num = random_num.Next(1, 100);//生成随机数
            label4!.Text = "随机数=" + Temp_int_num.ToString( );
            button1!.Enabled = false;          //停用开始按钮
        }
        /// <summary>
        /// 强行关闭窗体
        /// </summary>
        private void Form1_FormClosed(object? sender, FormClosedEventArgs e)
        {
            Environment.Exit(0);
        }
        /// <summary>
        /// 开始遍历100个按钮
        /// 清空窗体中动态生成的按钮
        /// </summary>
        void RemoveControl()
        {
            for (int i = 0; i < 100; i++)
            {
                if (Controls.ContainsKey((i + 1).ToString()))   //窗体中是否有此按钮
                {
                    for (int j = 0; j < Controls.Count; j++)    //遍历窗体控件集合
                    {
                        if (Controls[j].Name == (i + 1).ToString())//是否查找到按钮
                        {
                            Controls.RemoveAt(j);                  //删除指定按钮
                            break;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 用于查找窗体中Enable属性为False控件的数量
        /// 用于计算玩家有多少次没有猜中
        /// </summary>
        /// <returns>返回没有猜中数量</returns>
        string GetCount()
        {
            int P_int_temp = 0;                 //初始化计数器
            foreach (Control c in Controls)     //遍历控件集合
            {
                if (!c.Enabled) P_int_temp++;   //计数器累加
            }
            return P_int_temp.ToString();       //返回计数器信息
        }

        void Bt_Click(object? sender, EventArgs e)
        {
            Control? P_control = sender as Control; //将sender转换为control类型对象
            if (int.Parse(P_control!.Name) > Temp_int_num)
            {
                P_control.BackColor = Color.Red;     //设置按钮背景为红色
                P_control.Enabled = false;           //停用按钮
                P_control.Text = "大";               //更改按钮文本
            }
            if (int.Parse(P_control.Name) < Temp_int_num)
            {
                P_control.BackColor = Color.Red;     //设置按钮背景为红色
                P_control.Enabled = false;           //设置按钮停用
                P_control.Text = "小";               //更改按钮文本
            }
            if (int.Parse(P_control.Name) == Temp_int_num)
            {
                //thread1.Abort();
                CancellationToken cancellationToken = new();
                CancellationToken token = cancellationToken;
                Thread_Abort(token);
                MessageBox.Show(string.Format("恭喜你猜对了!共猜了{0}次 用时{1}秒",
                    GetCount(), label2!.Text), "恭喜!");  //显示游戏信息
                button1!.Enabled = true;                   //启用开始按钮
            }
        }
        /// <summary>
        /// 用于代替thread1!.Abort();
        /// SYSLIB0006:不支持 Thread.Abort
        /// </summary>
        static void Thread_Abort(CancellationToken cancellationToken)
        {         
                // If the CancellationToken is marked as "needs to cancel",
                // this will throw the appropriate exception.
                cancellationToken.ThrowIfCancellationRequested();
        }
    }
}

三、生成效果

?

文章来源:https://blog.csdn.net/wenchm/article/details/135322805
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。