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

news2025/1/20 13:18:04

目录

一、关于线程

二、示例 

三、生成效果


一、关于线程

        在使用多线程前要先引用命名空间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();
        }
    }
}

三、生成效果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1347984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++对于C语言的扩充】C++与C语言的联系,命名空间、C++中的输入输出以及缺省参数

文章目录 &#x1f680;前言&#x1f680;C有何过C之处&#xff1f;&#x1f680;C中的关键字&#x1f680;命名空间✈️为什么要引入命名空间&#xff1f;✈️命名空间的定义✈️如何使用命名空间中的内容呢&#xff1f; &#x1f680;C中的输入和输出✈️C标准库的命名空间✈…

VStudio2022导出Qt项目在Linux的Qtcreator中运行修复错误记录

公司项目中的代码在VStudio2022中编写&#xff0c;交给我需要移植Linux的Qtcreator中&#xff0c;记录一下移植过程中的遇到的坑&#xff0c;按照错误顺序由高到低记录一下&#xff0c;边尝试边解决边记录&#xff0c;写作方面没有逻辑&#xff0c;每个人项目环境不一样&#x…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取相机当前数据吞吐量(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK里函数来获取相机当前数据吞吐量&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的数据吞吐量的技术背景CameraExplorer如何查看相机吞吐量信息在NEOAPI SDK里通过函数获取相机接口吞吐量 Baumer工业相机通过NEOAPISDK获…

PHP与Angular详细对比 帮助你选择合适的项目技术

开发可有效扩展并提供诺克斯堡级安全性的Web应用程序和网站是每个开发人员的梦想。而使用这样的产品是每个用户的愿望。因此&#xff0c;为您的项目选择最合适和可靠的技术非常关键。 虽然PHP和Angular是完全不同的技术——PHP与JavaScript是一个更恰当的比较——但它们都广泛…

【JavaFX】JDK11 基于Gson、hutool、Jackson持久化存储实体类数据的解决方案 (读取、追加、去重、写入json对象)

文章目录 开发环境效果前言一、Gson是什么?二、使用步骤1.引入依赖2.创建实体类创建 JsonFileService类创建JsonFileService的实现类 JsonFileServiceImpl三、实现效果开发环境 JDK11IDEA 2023.3Gson、hutool、JacksonJavaFX 11效果 前言 使用JDK1

浅聊配置化-要不要实现动态表单

1、配置化的原则 配置化是一种抽象&#xff0c;把事物分成2类&#xff1a;不变的&#xff0c;可变的。 如果事物都是可变的&#xff0c;是无法实现配置化的。 配置化的根本在于找到不变的事物&#xff0c;基于不变的事物进行可变事物的配置。 所以&#xff0c;认为一切皆可…

Deeplearning4j 实战 (22):基于DSSM的语义匹配建模

Deeplearning4j 实战 &#xff08;22&#xff09;&#xff1a;基于DSSM的语义匹配建模 Eclipse Deeplearning4j GitChat课程&#xff1a;Deeplearning4j 快速入门_专栏 Eclipse Deeplearning4j 系列博客&#xff1a;万宫玺的专栏_wangongxi_CSDN博客 Eclipse Deeplearning4j G…

基于Spring Boot的美妆分享系统:打造个性化推荐、互动社区与智能决策

基于Spring Boot的美妆分享系统&#xff1a;打造个性化推荐、互动社区与智能决策 1. 项目介绍2. 管理员功能2.1 美妆管理2.2 页面管理2.3 链接管理2.4 评论管理2.5 用户管理2.6 公告管理 3. 用户功能3.1 登录注册3.2 分享商品3.3 问答3.4 我的分享3.5 我的收藏夹 4. 创新点4.1 …

【基础】【Python网络爬虫】【3.chrome 开发者工具】(详细笔记)

Python网络爬虫基础 chrome 开发者工具元素面板&#xff08;Elements)控制台面板&#xff08;Console&#xff09;资源面板&#xff08;Source&#xff09;网络面板&#xff08;Network&#xff09;工具栏Requests Table详情 chrome 开发者工具 ​ 当我们爬取不同的网站是&…

「微服务」Saga 模式 如何使用微服务实现业务事务-第二部分

在上一篇文章中&#xff0c;我们看到了实现分布式事务的一些挑战&#xff0c;以及如何使用Event / Choreography方法实现Saga的模式。在本文中&#xff0c;我们将讨论如何通过使用另一种类型的Saga实现&#xff08;称为Command或Orchestration&#xff09;来解决一些问题&#…

win10系统请将eNSP相关应用程序添加到windows firewall的允许程序列表,并允许其在公用网络上运行!的解决办法

很多学习网络的小伙伴&#xff0c;在下载安装eNSP后&#xff0c;打开程序跳出&#xff1a;请将eNSP相关应用程序添加到windows firewall的允许程序列表&#xff0c;并允许其在公用网络上运行! 是不是挺闹心的! 其实&#xff0c;原因是很简单&#xff0c;就是win10系统防火墙访…

Linux中安装了openjdk后jps command not found

一、问题场景 在Linux中用yum安装了openjdk-17&#xff0c;也在.bashrc中配置了环境变量JAVA_HOME以及bin目录的PATH。 但是在运行jps命令时依然报错找不到命令 二、原因分析 进入到$JAVA_HOME/bin目录查看&#xff0c;发现只有寥寥几个命令&#xff0c;压根没有jps命令&…

微信小程序发送模板消息-详解【有图】

前言 在发送模板消息之前我们要首先搞清楚微信小程序的逻辑是什么&#xff0c;这只是前端的一个demo实现&#xff0c;建议大家在后端处理&#xff0c;前端具体实现&#xff1a;如下图 1.获取小程序Id和密钥 我们注册完微信小程序后&#xff0c;可以在开发设置中看到以下内容&a…

4.35 构建onnx结构模型-Layernorm

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以 Layernorm 结点进行分析 方式 方法…

LAYABOX:2024新年寄语

2024新年寄语 过去的一年&#xff0c;尽管许多行业面临严峻挑战和发展压力&#xff0c;小游戏领域却逆势上扬&#xff0c;年产值首次突破400亿元大关&#xff0c;众多优质小游戏企业收获颇丰。 对此&#xff0c;祝福大家&#xff0c;2024一定更好&#xff01; 过去的一年&#…

Good Bye 2023

Good Bye 2023 Good Bye 2023 A. 2023 题意&#xff1a;序列a中所有数的乘积应为2023&#xff0c;现在给出序列中的n个数&#xff0c;找到剩下的k个数并输出&#xff0c;报告不可能。 思路&#xff1a;把所有已知的数字乘起来&#xff0c;判断是否整除2023&#xff0c;不够…

掌握C++11标准库(STL):理解STL的核心概念

深入探索C11标准库STL&#xff1a;新特性和优化技巧 一、前言二、容器简介三、迭代器简介四、map与unordered_map&#xff08;红黑树VS哈希表&#xff09;4.1、map和unordered_map的差别4.2、优缺点以及适用处4.3、小结 五、总结 一、前言 STL定义了强大的、基于模板的、可复用…

海康visionmaster-渲染控件:渲染控件加载本地图像的方法

描述 环境&#xff1a;VM4.0.0 VS2015 及以上 现象&#xff1a;渲染控件如何显示本地图像&#xff1f; 解答 思路&#xff1a;在 2.3.1 中&#xff0c;可以通过绑定流程或者模块来显示图像和渲染效果。因此&#xff0c;第一步&#xff0c; 可以使用在 VM 软件平台中给图像源模…

【网络面试(1)】浏览器如何实现生成HTTP消息

我们经常会使用浏览器访问各种网站&#xff0c;获取各种信息&#xff0c;帮助解决工作生活中的问题。那你知道&#xff0c;浏览器是怎么帮助我们实现对web服务器的访问&#xff0c;并返回给我们想要的信息呢&#xff1f; 1. 浏览器生成HTTP消息 我们平时使用的浏览器有很多种&…

LeetCode每日一题.04(不同路径)

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 示例 1…