首页 > 代码库 > [C#网络应用编程]2、对线程的管理

[C#网络应用编程]2、对线程的管理

在System.Threading命名空间下,有一个Thread类,用于对线程进行管理,如创建线程、启动线程、终止线程、合并线程、让线程休眠等

 Thread类 (假设Thread firTh = new 线程实例)

 firTh.IsBackground 返回一个bool值,判断或设置是否属于后台线程

默认情况下,属于托管线程池的线程(即IsThreadPoolThread为true)都属于后台线程,而通过创建并启动新的Thread对象生成的都属于前台线程。

如果使用一个线程监视某些活动(如Socket),可以将IsBackground设置为true,以遍该线程不会影响进程终止。

 

1、启动线程

Thread t1 = new Thread(方法名); //创建一个线程,该线程通过委托执行指定的方法,从.net2.0开始可以这么写,否则需要加ThreadStart

如果该方法带有参数,可以在启动时传递:
t1.Start(); //无参

t1.Start("I‘m param"); //有参数

参数只能有一个,只能是object类型,如果希望传递多个,可以把所有参数封装到一个类,再传该类的实例。

 

2、终止线程

有两种方法,第一种是事先设置一个bool值,在其他线程修改这个bool值表示是否需要终止,在该线程中循环判断该布尔值,以确定是否需要退出该线程。

第二种是调用Abort()方法,该方法的最终效果是强行终止该线程。但线程实际上不一定会立即结束,因为系统在结束线程前要进行代码清理工作,这需要一定的时间,因此在调用Abort()方法后,如果自动清理工作还未结束,可能会出现类似于死机的假死现象。为了解决这个问题,可以在主线程中调用Join()方法,并在Join方法中指定主线程等待子线程结束的等待时间。

推荐第一种方法,实际工作中也是一般使用第一种方法。

 

3、暂停线程

Thread.Sleep(int 毫秒) 该方法为静态方法

 

4、合并线程

t1.Join(); 

如果线程t1需要在线程t2执行结束才继续执行,可以在t1中调用t2.Join(),但是如果t2一直不执行完,那么t1也无法执行,因此可以给Join加一个参数:

t1.Join(1000); 这样t1至多只会等待1000毫秒,然后无论t2是否结束,都继续往下执行。

 

在一个线程中访问由另一个线程创建的控件

直接访问会报异常:从不是创建控件的线程访问它。 现在有两种办法可以实现这个功能:

第一种是使用委托和事件完成。

第二种是利用BackroundWorker组件实现。

 

1. 委托

首先在类里面定义一个委托

然后在需要用到的地方实例化委托

通过控件的InvokeRequired判断该控件是否属于该线程,并使用委托或者直接调用需要的方法:

 

public partial class Form1 : Form {        delegate void ToAddSth(string item);  //在类中定义委托        ...        private void AddMessage(string item)        {                        ToAddSth myDele = new ToAddSth(AddMessage); //实例化委托            if(TextBox1.InvokeRequired)   //根据控件的InvokeRequired判断是否需要委托            {                 TextBox1.Invoke(myDele,item);  //利用委托            }            else            {                 TextBox1.Items.Add(item);  //直接调用            }        } } 

 

 

 

volatile修饰符

volatile修饰符表示所声明的字段可以被多个并发执行的线程修改。如果某个字段声明包含volatile,则该字段将不再被编译器所优化,这样确保它在任何时间呈现的都是最新值。

对于多个线程访问的字段,而且该字段没有用lock语句对访问进行序列化,则应该用volatile进行声明。

volatile修饰符只能包含在类或结构的声明中,不能将局部变量声明为volatile。

 

class Class1    {        public volatile bool shouldStop;//这里设置为volatile是关键,否则不能及时控制,该关键字无法修饰属性,直接用属性也不能及时控制        private Form1 form1;        public Class1(Form1 form)        {            this.form1 = form;        }        public void Method1(object obj)        {            string msg = obj as string;            while (!shouldStop) //当开关打开一直循环            {                Thread.Sleep(100);                form1.AddMessage(msg);            }             form1.AddMessage("now a stoped!");//跳出循环        }        public void Method2()        {            while (!shouldStop)            {                Thread.Sleep(100);                 form1.AddMessage("b");            }            form1.AddMessage("now b stoped!");        }    }
public partial class Form1 : Form    {        Process process1 = new Process();        delegate void ToAddSth(string item);        Class1 c1;        Thread th1, th2;                public Form1()        {            InitializeComponent();            c1 = new Class1(this);            button1.Click += new EventHandler(button1_Click);            button2.Click += new EventHandler(button2_Click);        }        private void button1_Click(object sender, EventArgs e)        {            TextBox1.Text="";            th1 = new Thread(c1.Method1);            th2 = new Thread(c1.Method2);            th1.IsBackground = true;            th2.IsBackground = true;            th1.Start("a start");            th2.Start();        }        private void button2_Click(object sender, EventArgs e)        {            c1.shouldStop = true;        }    }

 

 

 

 

[C#网络应用编程]2、对线程的管理