C#之线程Thread
目录
Thread
创建线程
线程的挂起、恢复、休眠与终止
线程的优先级ThreadPriority
线程同步的Lock关键字
线程监视器Monitor
线程池用法
WinForm中跨线程控件访问
解决方案一:CheckForIllegalCrossThreadCalls
解决方案二:委托
Thread
进程——搬运小组 线程——小组成员 主线程——组长
进程:一个正在运行的应用程序就是一个进程,可以有一个或多个线程
线程:线程是进程中可以并行执行的程序段
创建线程
创建WinForm项目
public void Form1_Load(object sender, EventArgs e)
{//创建线程Thread th1 = new Thread(TestThread);th1.Start();
}private void TestThread()
{MessageBox.Show("OK");
}
运行程序:
线程的挂起、恢复、休眠与终止
效果:
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
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关键字
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
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);}
}
执行结果:
线程池用法
public void Form1_Load(object sender, EventArgs e)
{ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPooTest));
}private void ThreadPooTest(object state)
{MessageBox.Show("调用成功");
}
执行结果:
WinForm中跨线程控件访问
新建一个按钮为跨线程访问用来访问RichTextBox控件
private void button13_Click_1(object sender, EventArgs e)
{//在Button中创建线程访问主线程的FuncTestThread th1 = new Thread(FuncTest);th1.Start();
}private void FuncTest()
{this.textLog.Text = "1234";
}
解决方案一:CheckForIllegalCrossThreadCalls
public Form1()
{InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false;//禁止跨线程调用时的一些机制检查
}
运行程序点击按钮:
解决方案二:委托
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中创建线程访问主线程的FuncTestThread th1 = new Thread(FuncTest);th1.Start();}private void FuncTest(){this.Invoke(myDel);}
}