C#应用实训|任务1 线程实现页面刷新
发布者:唯众
布时间:2020-12-14 16:59:00
点击量:
任务描述
项目运行通过随机函数模拟生成温度及光敏随机数据,通过后台线程获取随机数据并显示,数据每隔5秒自动刷新,项目运行过程中对数据进行分析,如果温度超过30度,则打开风扇,否则关闭风扇,如果如果光敏大于100,则打开RGB灯,否则关闭RGB灯。
知识引入
- 线程
线程(英语:thread)是操作系统能够进行运算调度的最小单位,一个进程中可以并发多个线程,每条线程并行执行不同的任务,多个线程并发执行能提高程序执行效率,C#支持多线程并发,C#能过命名空间System.Threading支持线程对象,Thread类用来创建线程对象,如:
Thread t1=new Thread(show);
Show为要执行的方法,Thread类的常用属性如表5-1所示:
表5-1 Thread类常用属性表
属性 |
说明 |
CurrentContext |
获取线程正在其中执行的当前上下文 |
CurrentThread |
获取当前正在运行的线程 |
IsAlive |
判断当前线程是否处于活动状态 |
IsBackground |
获取或设置取或设置线程是否为后台线程。 |
Name |
获取或设置线程的名称 |
ThreadState |
当前线程的状态 |
Thread类的常用方法如表5-2所示:
表5-2 Thread类常用方法表
方法 |
说明 |
public void Abort() |
终止此线程的过程,调用此方法通常会终止此线程 |
public void Interrupt() |
中断处于 WaitSleepJoin 线程状态的线程 |
public void Join() |
阻塞调用线程 |
public static void ResetAbort() |
取消为当前线程请求的 Abort |
public void Start() |
线程启动运行 |
public static void Sleep( ) |
让线程暂停一段时间 |
【
例5-1】
static void Main(string[] args)
{
Thread t = new Thread(show);
t.Start();
for (int i = 0; i < 50; i++)
{
Console.WriteLine("ok");
}
}
static void show()
{
for (int i = 0; i < 50;i++ )
{
Console.WriteLine("hello");
}
}
Thread实类对象t通过构造方法new Thread(show)进行实例化,参数为方法show,表示线程要做的事情,线程通过start( )方法启动执行,程序执行时Main方法为主线程,在主线程中输出“ok”,t1为子线程,子线程启动后输出“hello”,主线程和子线程并发执行,通过输出结果观察,可以看到“hello”和“ok”会交叉输出。如图5-4所示:
图5-4 程序运行效果图
【
例5-2】
static void Main(string[] args)
{
Thread t = new Thread(print);
t.Start();
}
public static void print()
{
for (int i = 5; i>0; i--)
{
Console.WriteLine(i);
Thread.Sleep(i * 1000);
}
}
程序运行输出5,4,3,2,1。输出时间越来越快,通过Thread.Sleep()方法可以使线程睡眠一段时间,时间单位为毫秒,1000为1秒。
- Random类
Random类表示随机数生成器,通过Random类可以产生满足条件的随机数,Random类有两种构造方法,分别为:
Random( ):表示根据当前系统时间为种子,产生随机数
Random( Int32):表示根据设定的种子产生随机数
因为计算机的运行速度很快,如果根据当前时间为种子,连续产生的随机数可能都是重复的,因此Random称为伪随机数生成器,一般在应用中根据需要,使用算法产生一系列相对重复度比较小的随机数,Random实例对象主要通过Random类的方法生成随机数,Random类的主要方法如表5-3所示:
表5-3 Random类常用方法表
方法 |
说明 |
Next () |
返回一个非负随机整数 |
Next( Int32) |
返回一个小于所指定最大值的非负随机整数 |
Next( Int32,Int32) |
返回在指定范围内的任意整数 |
NextDouble( ) |
返回一个大于或等于 0.0 且小于 1.0 的随机浮点数 |
Sample( ) |
返回一个大于或等于 0.0 且小于 1.0 的随机浮点数,该方法为protected,访问级别不同,其它方法为public。 |
【
例5-2】
static void Main(string[] args)
{
Random rand = new Random();
Console.WriteLine(rand.Next());
Console.WriteLine(rand.Next(5));
Console.WriteLine(rand.Next(5,10));
Console.WriteLine(rand.NextDouble());
}
程序运行分别输出不同范围的数据。
- 跨线程更新UI
在多线程操作中,如果子线程需要访问主线程创建的控件,特别是子线程希望随时更新主线程创建控件的外观,在.NET2.0后系统可能会抛出异常,导致程序不能运行。这主要是出于安全考虑,CheckForIllegalCrossThreadCalls的值在.NET2.0后默认为true,表示在访问非创建线程控件时会进行安全考虑,系统将抛出异常。
【
例5-3】
新建一个Windows窗体项目,程序界面如图5-5所示:
图5-5 程序界面效果图
如果要实现当点击按钮“button1”后,上面的标签在“红色”变为“蓝色”,并且每隔2 秒在两种颜色之间进行切换。编写“button1”的click事件代码如下:
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(setText);
t.IsBackground = true;
t.Start();
}
private void setText()
{
while(true)
{
if(label1.Text.Equals("红色"))
{
label1.Text = "蓝色";
}
else
{
label1.Text = "红色";
}
Thread.Sleep(2000);
}
}
程序运行,点击按钮“button1”后,程序报错,抛出异常。如图5-6所示:
图5-6 程序运行报错图
这时将窗口构造函数中的CheckForIllegalCrossThreadCalls设置为false,程序将不进行安全检查,正常执行。
任务实现
- 新建Windows窗体应用程序项目,添加控件及属性设置如表5-4所示:
表5-4 窗体控件及属性设置表
控件 |
属性 |
值 |
Form1 |
Text |
智能大棚控制系统 |
Form1 |
Size |
480,360 |
Label1 |
Text |
智能大棚控制系统 |
Label2 |
Text |
当前温度 |
Label3 |
Text |
null |
Label3 |
Name |
lblTemp |
Label4 |
Text |
当前光敏 |
Label4 |
Name |
lblPhoto |
Label5 |
Text |
风扇状态 |
Label6 |
Text |
关闭 |
Label6 |
Name |
lblFs |
Label7 |
Text |
RGB灯状态 |
Label8 |
Text |
关闭 |
Label8 |
Name |
lblRgb |
- 添加页面事件代码如下:
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
Thread t = new Thread(setVal);
t.IsBackground = true;
t.Start();
}
//随机生成温度
private int getWd()
{
int result = -1;
Random rand = new Random();
result = rand.Next(20,35);
return result;
}
//随机生成光敏
private int getPhoto()
{
int result = -1;
Random rand = new Random();
result = rand.Next(50, 150);
return result;
}
//读取值
private void setVal()
{
while(true){
int wdNum = getWd();
lblTemp.Text =wdNum.ToString();
if (wdNum >= 28)
{
lblFs.Text="打开";
}
else
{
lblFs.Text = "关闭";
}
int photoNum = getPhoto();
lblPhoto.Text = photoNum.ToString();
if (photoNum >= 100)
{
lblRgb.Text = "打开";
}
else
{
lblRgb.Text = "关闭";
}
Thread.Sleep(5000);
}
}
任务小结
- 线程是操作系统运算调度的最小单位,多线程协作能提高程序执行效率。
- 线程有多种状态,线程通过start()启动执行,通过sleep()进入睡眠状态。
- 子线程访问主线程控件状态可能抛出异常信息。
上一篇:C#应用实训|项目五 智能大棚控制系统
下一篇:C#应用实训|任务2 委托实现页面刷新