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);
    }
}
相关推荐
淡海水1 小时前
00-Unity和C#的GC剖析与对比-全篇导览
unity·c#·游戏引擎·gc
fogota2 小时前
C# `string.Join` 处理 `List<int>`
windows·c#
Behavior4 小时前
Unity 手游动态更换 App 图标 — Android 与 iOS 双端技术方案
c#·unity3d·游戏开发
周杰伦fans5 小时前
构建真正智能的CAD AI绘图代理
开发语言·人工智能·c#
UIU1148 小时前
递归算法与汉诺塔
c++·学习·算法·c#·递归
CSharp精选营13 小时前
我用 ASP.NET Core 做了个水稻病虫害检查系统
c#·毕业设计·.net core·码农刚子
唐青枫13 小时前
我用 C# 开发了一款电子发票自动整理工具
c#·.net
下页、再停留14 小时前
【C#桌面客户端系列学习-2】在原来窗口基础上打开新窗口
c#·visual studio
Behavior14 小时前
Unity 手游 iOS Deep Link 唤醒全流程:从 URL Scheme / Universal Links 到 C# 层参数投递
c#·unity3d·游戏开发
我是唐青枫14 小时前
我用 C# 开发了一款电子发票自动整理工具
c#·.net