----------------------
ASP.Net+Android+IO开发S、
.Net培训、期待与您交流! ----------------------
多线程方法重入问题:
----------------------
ASP.Net+Android+IO开发S、
.Net培训、期待与您交流! ----------------------
1.进程与线程
一个进程至少有一个线程
同一个进程中的多个线程可以“并发”执行
线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针,程序计数器等),但代码区是共享的,即不同的线程可以执行相同的函数
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同线程来执行不同的任务(代码),也就是说允许单个程序创建多个并行执行的线程来完成自己的任务
2..NET如何实现多线程
1.声明方法
2.声明委托类型
3.创建委托对象
4.启动线程
2.声明委托类型
3.创建委托对象
4.启动线程
Thread类的一些重要成员:
Start()启动线程
Abort()终止线程
Sleep() 静态方法,可以使当前线程停止一段时间运行
Name线程名
Thread.CurrentThread获得当前的线程引用
Abort()终止线程
Sleep() 静态方法,可以使当前线程停止一段时间运行
Name线程名
Thread.CurrentThread获得当前的线程引用
单线程的缺点:
private void btnSingleThread_Click(object sender, EventArgs e)
{
for (int i = 0; i < 999999999; i++)
{
}
MessageBox.Show("循环完毕");
}
程序启动,调用主线程UI线程去执行循环,循环完毕之前,会出现界面卡死现象
多线程的优点:
1) 让计算机“同时”做多件事情,节约时间
2) 后台运行程序,提高程序的运行效率,也不会使主界面出现无响应的情况
3) 多线程可以让一个程序“同时”处理多个事情
4) 充分利用CPU资源,计算机大部分时间都处于空闲状态
private static void CountTime()
{
for (int i = 0; i < 999999999; i++)
{
}
MessageBox.Show("循环完毕");
}
//使用多线程来解决UI界面卡死问题
private void btnMuiThread_Click(object sender, EventArgs e)
{
//创建线程 传入线程要执行的方法
Thread thread1 = new Thread(CountTime);
//线程的 启动方法
thread1.Start();
}
现在把循环提取成一个单独的方法,然后创建另外一个线程去执行CountTime()方法,就不会出现主界面卡死了
产生现成的4个步骤:
编写线程所要执行的方法
添加using System.Threading;引用
实例化Thread类,并传入线程所要执行的方法(这时候线程已经产生,还没有运行)
调用Thread实例的Start()方法,标记该线程可以被CPU执行了,但具体什么时候执行看CPU决定
前台线程和后台线程:
前台线程:只有所有的前台线程都关闭才能完成程序关闭
后台线程:只要所有的前台线程结束,后台线程自动结束
程序中设置后台线程的方法:
//IsBackground是否为后台线程,默认属性为false(前台线程),设置为true时为后台线程
thread4.IsBackground = true;
多线程方法重入问题:
public Form1()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;
}
void CountTime()
{
for (int i = 0; i < 2000; i++)
{
int a = int.Parse(txtNum.Text);
Console.WriteLine(Thread.CurrentThread.Name+",a="+a);
a++;
txtNum.Text = a.ToString();
}
MessageBox.Show("循环完毕");
}
private void btnPro_Click(object sender, EventArgs e)
{
//创建线程 2
Thread thread2 = new Thread(CountTime);
//给线程命名
thread2.Name = "thread2";
//设置为后台线程
thread2.IsBackground = true;
//线程2 启动
thread2.Start();
Thread thread3 = new Thread(CountTime);
thread3.Name = "thread3";
thread3.IsBackground = true;
thread3.Start();
}
两个线程同时执行CountTime()方法,两个互不干扰,都会把方法执行完,CPU在两个线程之间切换执行
Thread类:
public sealed class Thread : CriticalFinalizerObject, _Thread
{
//带参数委托的构造函数
public Thread(ParameterizedThreadStart start);
//不带参数委托的构造函数
public Thread(ThreadStart start);
}
Thread类构造函数用到的两个委托:
//带参数的委托 object类型的参数
public delegate void ParameterizedThreadStart(object obj);
//不带参数的委托
public delegate void ThreadStart();
//自己仿写Thread类
public class MyThread
{
private ThreadStart ts;
public ThreadStart Ts
{
get { return ts; }
set { ts = value; }
}
public MyThread(ThreadStart ts)
{
this.ts = ts;
}
public void Start()
{
ts();
}
private ParameterizedThreadStart pts;
public ParameterizedThreadStart Pts
{
get { return pts; }
set { pts = value; }
}
public MyThread(ParameterizedThreadStart pts)
{
this.pts = pts;
}
public void Start(object obj)
{
pts(obj);
}
}
线程实现带参数的方法:
void Test2(object name)
{
MessageBox.Show(name.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
ParameterizedThreadStart pts = new ParameterizedThreadStart(Test2);
MyThread mythread2 = new MyThread(pts);
mythread2.Start(txtNum.Text);
}
线程实现带多个参数的方法:
public static void Test3(object li)
{
List<int> list = new List<int>();
list = li as List<int>;
//list = (List<int>)li;
if (list != null)
{
foreach (int i in list)
{
MessageBox.Show(i.ToString());
}
}
}
private void button1_Click(object sender, EventArgs e)
{
ParameterizedThreadStart pts2 = new ParameterizedThreadStart(Test3);
MyThread mythread3 = new MyThread(pts2);
mythread3.Start(new List<int>(){1,2,3,4,5,6});
}