目录
解决方案一: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);
}
}
