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);
    }
}
相关推荐
Dm_dotnet21 小时前
WPF Stylet可以如何实现导航功能?
c#
谷宇.1 天前
【Unity3D实例-功能-移动】角色行走和奔跑的相互切换
游戏·unity·c#·unity3d·游戏开发·游戏编程
ts码农1 天前
Aspose使用
c#·aspose
专注VB编程开发20年2 天前
c#,vb.net全局多线程锁,可以在任意模块或类中使用,但尽量用多个锁提高效率
java·前端·数据库·c#·.net
岩屿2 天前
.NET 应用程序 Linux下守护进程脚本编写
linux·运维·服务器·c#·.net
军训猫猫头2 天前
11.用反射为静态类的属性赋值 C#例子 WPF例子
开发语言·c#
一枚小小程序员哈2 天前
基于C#、.net、asp.net的心理健康咨询系统设计与实现/心理辅导系统设计与实现
c#·asp.net·.net
Crazy Struggle2 天前
告别手动更新!WinForm 应用轻松集成自动升级功能 (HHUpdateApp)
c#·winform·自动更新
Archy_Wang_12 天前
ASP.NET 上传文件安全检测方案
后端·c#·asp.net
sali-tec2 天前
C# 基于halcon的视觉工作流-章29-边缘提取-亚像素
开发语言·图像处理·算法·计算机视觉·c#