C#之线程Thread

目录

Thread

创建线程

线程的挂起、恢复、休眠与终止

线程的优先级ThreadPriority

线程同步的Lock关键字

线程监视器Monitor

线程池用法

WinForm中跨线程控件访问

解决方案一:CheckForIllegalCrossThreadCalls

解决方案二:委托


Thread

进程------搬运小组 线程------小组成员 主线程------组长

进程:一个正在运行的应用程序就是一个进程,可以有一个或多个线程
线程:线程是进程中可以并行执行的程序段

创建线程

创建WinForm项目

cs 复制代码
public void Form1_Load(object sender, EventArgs e)
{
    //创建线程
    Thread th1 = new Thread(TestThread);
    th1.Start();
}


private void TestThread()
{
    MessageBox.Show("OK");
}

运行程序:

线程的挂起、恢复、休眠与终止

效果:

cs 复制代码
Thread th1;

public void Form1_Load(object sender, EventArgs e)
{
    //创建线程
    th1 = new Thread(TestThread);
    //启动线程
    th1.Start();
}

private void TestThread()
{
    while (true)  //在这里打断点,点击线程挂起按钮可以看到线程挂起就不会再进来了,点击线程恢复又会进来
    {
        Thread.Sleep(10000);  //10s  写在这里是休眠th1线程,窗体还可以做除此之外的操作
        Console.WriteLine("===================="+DateTime.Now);
    }
}

#region Thread
private void button13_Click(object sender, EventArgs e)
{
    //线程挂起
    th1.Suspend();
}

private void button14_Click(object sender, EventArgs e)
{
    //线程恢复
    th1.Resume();
}

private void btnThreadSleep_Click(object sender, EventArgs e)
{
    //线程休眠
    Thread.Sleep(10000);  //10s  4.写在这里是休眠主线程,运行程序点击线程休眠按钮窗体休眠不能做任何操作
}

private void btnThreadAbore_Click(object sender, EventArgs e)
{
    th1.Abort();  //线程终止
}
#endregion

线程的优先级ThreadPriority

cs 复制代码
public class TheadClass
{
    Thread th2;
    Thread th3;

    public TheadClass()
    {
        th2 = new Thread(Test1);
        th3 = new Thread(Test2);

        //优先级设置不是绝对的
        th2.Priority = ThreadPriority.Highest; //Thead指定的调用优先级------最高
        th3.Priority = ThreadPriority.Lowest; //Thead指定的调用优先级------最低
        th2.Start();
        th3.Start();
    }

    private void Test1()
    {
        for (int i = 0; i < 10000; i++)
        {
            Console.WriteLine("AAAAAAAAAAAA");
        }
    }

    private void Test2()
    {
        for (int i = 0; i < 10000; i++)
        {
            Console.WriteLine("BBBBBBBBBBBB");
        }
    }
}

运行效果:

这里我只打印了六十行方便截图

可以看到A的打印优先级高于B。

线程同步的Lock关键字

cs 复制代码
public void Form1_Load(object sender, EventArgs e)
{
    Account account = new Account();
    for (int i = 0; i < 3; i++) 
    { 
        Thread th = new Thread(account.ToFA);
        th.Start();
        //第一个线程创建后第二个线程通过Lock关键字形成互斥锁,第二个线程要等第一个线程完成后才创建执行
    }
}

class Account 
{
    private int i = 0;
    public void ToFA()
    {
        lock (this) //锁的是Account
        {
            Console.WriteLine("账户余额:" + i.ToString());
            Thread.Sleep(5000);  //线程休眠模拟耗时操作
            i += 1000; //i自增
            Console.WriteLine("转账后的账户余额是:"+i);
        }
    }
}

执行效果:

如果注释Lock关键字执行:

线程监视器Monitor

cs 复制代码
public void Form1_Load(object sender, EventArgs e)
{
    //Monitor
    //当一个线程拥有对象锁的时候,其他任何线程都不能获取该锁
    TestMonitor test = new TestMonitor();
    for (int i = 0; i < 3; i++) 
    {
        Thread th = new Thread(test.TestRun);
        th.Start();
    }
}

class TestMonitor
{
    private Object obj = new Object();
    private int i = 0;

    public void TestRun()
    { 
        Monitor.Enter(obj); //在同步对象上获取排他锁
        Console.WriteLine("账户余额:" + i.ToString());
        Thread.Sleep(5000);
        i += 1000;
        Console.WriteLine("转账后的余额是:" + i);
        Monitor.Exit(obj);
    }
}

执行结果:

线程池用法

cs 复制代码
public void Form1_Load(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPooTest));
}

private void ThreadPooTest(object state)
{
    MessageBox.Show("调用成功");
}

执行结果:

WinForm中跨线程控件访问

新建一个按钮为跨线程访问用来访问RichTextBox控件

cs 复制代码
private void button13_Click_1(object sender, EventArgs e)
{
    //在Button中创建线程访问主线程的FuncTest
    Thread th1 = new Thread(FuncTest);
    th1.Start();
}

private void FuncTest()
{
    this.textLog.Text = "1234";
}

解决方案一:CheckForIllegalCrossThreadCalls

cs 复制代码
public Form1()
{
    InitializeComponent();

    Control.CheckForIllegalCrossThreadCalls = false;//禁止跨线程调用时的一些机制检查
}

运行程序点击按钮:

解决方案二:委托

cs 复制代码
public delegate void SetThreadTest();  //定义一个委托:类似于定义一个类
public partial class Form1 : Form
{
    SetThreadTest myDel;
    public Form1()
    {
        InitializeComponent();

        //Control.CheckForIllegalCrossThreadCalls = false;//禁止跨线程调用时的一些机制检查
        myDel = new SetThreadTest(MyDelFunTest);
    }

    private void MyDelFunTest()
    {
        this.textLog.Text = "1234";
    }

    private void button13_Click_1(object sender, EventArgs e)
    {
        //在Button中创建线程访问主线程的FuncTest
        Thread th1 = new Thread(FuncTest);
        th1.Start();
    }

    private void FuncTest()
    {
        this.Invoke(myDel);
    }
}
相关推荐
波波00744 分钟前
写出稳定C#系统的关键:不可变性思想解析
开发语言·c#·wpf
willhuo1 小时前
基于Playwright的抖音网页自动化浏览器项目使用指南
爬虫·c#·.netcore·webview
光泽雨2 小时前
c#文件结构
c#
南無忘码至尊3 小时前
Unity学习90天-第2天-认识键盘 / 鼠标输入(PC)并实现WASD 移动,鼠标控制物体转向
学习·unity·c#·游戏开发
William_cl4 小时前
C# ASP.NET 分层架构实战:BLL (Service) 业务层从入门到封神(规范 + 避坑)
架构·c#·asp.net
qq_454245035 小时前
图数据标准化与智能去重框架:设计与实现解析
数据结构·架构·c#·图论
CSharp精选营5 小时前
C# 如何减少代码运行时间:7 个实战技巧
性能优化·c#·.net·技术干货·实战技巧
hhh3u3u3u18 小时前
Visual C++ 6.0中文版安装包下载教程及win11安装教程
java·c语言·开发语言·c++·python·c#·vc-1
加号318 小时前
【C#】实现沃德普线光控制器通信控制(附完整源码)
开发语言·c#
lzhdim20 小时前
SharpCompress:跨平台的 C# 压缩与解压库
开发语言·c#