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);
    }
}
相关推荐
Maybe_ch5 小时前
WinForm-免费,可商用的WinForm UI框架推荐
windows·ui·c#
这是我588 小时前
unity实现梦日记式效果
unity·c#·游戏引擎·unity3d·游戏开发·csharp·c#11.0
AI、少年郎10 小时前
从 C# 到 Python:项目实战第五天的飞跃
开发语言·数据库·c#
大飞pkz13 小时前
【设计模式&C#】工厂方法模式(相比简单工厂模式更加具有灵活性和扩展性的工厂模式)
开发语言·设计模式·c#·工厂方法模式
浮生带你学Java15 小时前
Spring 中的 Bean 作用域(Scope)有哪些?各自适用于什么场景?
开发语言·jvm·c#
曲幽15 小时前
C#解析JSON数据全攻略
c#·httpclient·webclient·tojson
唐青枫18 小时前
C#.NET 并发令牌 详解
c#·.net
柠檬味的薄荷心1 天前
【C#补全计划:类和对象(一)】
开发语言·c#
AI、少年郎2 天前
从 C# 转 Python 第三天:文件操作、异常处理与错误日志实践
java·前端·数据库·c#·异常处理·文件操作