序: 我是自学的C#,在看到多线程一章时,郁闷了,搞不懂,很难理解吧...自认为有软件天赋,却没看懂...唉...自信心被打击了,到网上查了很多的资料,包括MSDN 上也查过资料,可惜还是没搞懂多线程... 于是,硬着头皮一遍一遍的看多线程那一章,终于在看完第31遍,我写出了第一个多线程程序,还算小有所获,鉴于对网上很多资料没办法理解(因为,很多资料一来就大篇大篇 的代码,让人头晕,我是这么觉得)所以,我自己就写了这篇心得体会,希望能给大家带来些许帮助. 匆忙之中,错误难免,欢迎指正,共同进步. 正文: 首先我要提一点,关于线程的基础知识,一个程序,即一个进程,可以有很多个线程,当然,至少要有一个线程,即主线程.相信大家都知道多线程的好处吧,举个书上的例子 吧,Windows在复制文件的时候,有个动画,是在复制文件过程中进行的,也就是一边复制文件,一边播放动画,这个就是很简单的多线程,如果没有动画,复制一个大文件的时候,我们知 道计算机是死机了,还是仍然在复制呢???多线程就很好的解决了这个问题.懂了吧,恩,很好!!那么,我们就开始吧! 首先,我们写个简单的单线程程序,也就是只有程序自己创建的那个主线程,没有使用多线程. 创建一个新工程,向窗口添加一个label命名为label1;我们要让程序运行时label1就显示一个数字,假设为100;通常我们会直接在窗口加载事件中写label1.Text = "100";这样,运行 ,label1果然显示了100; 代码如下:(例1) using System; namespace ThreadTest private void Form1_Load(object sender, EventArgs e) 很简单吧,看懂了吗?? 什么,没有,啊~~~神啊~~~救救我吧,那请你在翻书,把最最最最最基础的书翻出来看看里面的最最最最最简单例子(以后不要说我认识你) 好了,看懂的朋友继续往下看: 我们现在要将程序稍稍改动一下,添加一个Button,命名为button1,我们要在按下button1后,将lable1的text从0显示到100, 代码如下:(例2) using System; namespace ThreadTest private void Form1_Load(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) 运行一下看看,按一下button1,结果是我们一下就看到了100,并没有看到0~100的过程,为什么呢? 整个代码如下:(例3) using System; namespace ThreadTest private void Form1_Load(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) private void run() 添加一个timer, 命名为timer1,在timer1的tick事件内添加语句,改变label1的值。(Tick事件是每经过指定时间间隔后被触发) 代码如下:(例4) using System; namespace ThreadTest public Form1() private void Form1_Load(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) private void run() private void timer1_Tick(object sender, EventArgs e) //timer1的Tick事件 同样的,我们运行一下,看看结果,很好,我们能够看到0~100循环的过程了。 下面我们就要进入多线程了,不知道各位将上面的内容看懂了没有? 开始进入多线程之前我还是先简单的说说定义线程吧。(与多线程有关的其它内容我就不说了吧,那个太多太多了) 创建线程就算完成了,那么怎么运行线程呢? 好了,大功告成!哈哈,别着急,既然我们创建了线程,那么在关闭窗口的时候,就要撤消线程。 private void Form1_FormClosing(object sender, FormClosingEventArgs e) 这样才算大功告成嘛,整理的代码如下:(例5)(在例3的基础上加以改动) using System; namespace ThreadTest public Form1() private void Form1_Load(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) private void run() private void Form1_FormClosing(object sender, FormClosingEventArgs e) 运行看看,按button1,出错了,怎么回事呢???? 哈哈~~我来解释一下,出错的原因是为了保护数据的安全所以不能跨线程调用控件,而label1.Text = i.ToString();句则是在线程thread1上面调用主线程的控件,肯定会出错的 !! 首先看一个例子:(从例3改写)(并不创建线程,仅有主线程) private void set_lableText(string s) 整理代码如下:(例6) using System; namespace ThreadTest private void Form1_Load(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) private void run() private void set_lableText(string s) 实现的功能与例3是一样的,只是,增加了一个函数。 现在再来看看委托,我们就需要委托主线程调用函数set_lableText(string s);来改变lable1的值。 首先声明一个委托: 创建一个全局委托变量:(应该是变量吧) 类似于创建线程,需要进行实例化: 现在,就剩下调用委托了,怎么调用委托呢?很简单。 整理代码如下:(例7) using System; namespace ThreadTest delegate void set_Text(string s); //定义委托 set_Text Set_Text; //定义委托 public Form1() private void Form1_Load(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) private void set_lableText(string s) //主线程调用的函数 private void run() private void Form1_FormClosing(object sender, FormClosingEventArgs e) 这样,一个简单的多线程程序就算完成了。 结语: |