首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

ManualResetEvent用法 线程间操作无效: 从未有过是创建控件“XXX”的线程访问它

2012-12-25 
ManualResetEvent用法线程间操作无效: 从不是创建控件“XXX”的线程访问它转之:http://blog.tom.com/blog/re

ManualResetEvent用法 线程间操作无效: 从不是创建控件“XXX”的线程访问它

转之:http://blog.tom.com/blog/read.php?bloggerid=313638&blogid=13505及http://hi.baidu.com/zsw_crown/blog/item/edba49123a32550f5baf53a6.html

ManualResetEvent用法

别相信别人告诉你的所有的事。其实C#中的线程是很简单的。
线程是程序中的控制流程的封装。你可能已经习惯于写单线程程序,也就是,程序在它们的代码中一次只在一条路中执行。如果你多弄几个线程的话,代码运行可能会更加“同步”。在一个有着多线程的典型进程中,零个或更多线程在同时运行。但是,在有着N个CPU的机器上,一个线程只能在给定的时间上在一个CPU上运行,因为每个线程都是一个代码段,每个CPU一次只能运行一段代码。而看起来像是N个同时完成是线程间共享CPU时间片的效果。这个例子里,我们将创建另一个线程,我们将用两个线程演示多线程的工作方式,最后,我们实现两个线程(主线程与新线程)同步,在新线程工作前必须等待消息。建立线程前我们必须引入System.Threading命名空间。然后我需要知道的是,线程得为控制流程建立一个起点。起点是一个函数,可以使一个相同的调用或其它。
这里你可以看到在同一个类中定义的起点函数。

?Thread.Sleep(n)方法把“this”线程置于n毫秒的休眠状态。你可以看看这个例子,在主函数我们定义了一个新的线程,其中它的起点是函数trmain(),我们然后包含了Start()方法开始执行。如果你运行这个例子,你就会了解线程间的切换(让CPU从运行一个线程转到另一个线程)让线程几乎同时运行,为了能看哪个线程运行更快我把主线程设置比新线程少100毫秒。
现在,在开始线程前,先给线程命名:
? Thread thrd1=new Thread(new ThreadStart(trmain));
? thrd1.Name="thread1";
? thrd1.Start();
? Thread tr = Thread.CurrentThread;
? Console.WriteLine(tr.Name);
在完成上面程序后,设想我们不想在一开始新线程就让它马上运行结束,也就是说,我们开启了一个新线程,让它运行,在某个特定的时间点,新线程暂停并等待从主线程(或其他线程)发来的消息。
我们可以这样定义:
? public static ManualResetEvent mre = new ManualResetEvent(false);
ManualResetEvent建立时是把false作为start的初始状态,这个类用于通知另一个线程,让它等待一个或多个线程。注意,为了通知或监听同一个线程,所有的其它线程都能访问那个类。
等待线程这样写:
? mre.WaitOne();
这将引起等待线程无限期的阻塞并等待类来通知。
发信号的线程应该这样:
? mre.Set();
这样类就会被通知,值变成true,等待线程就会停止等待。在通知事件发生后,我们就可以使用下面语句把线程置于基状态:
? mre.Reset();
现在让我们在程序执行一下:

?大家有没有注意到,但我们在一个控件的事件中启动一个线程的话:

?

试试会有什么后果.呵呵 "线程间操作无效: 从不是创建控件“textBox2”的线程访问它。" 会出现这个错误的.

怎么办.

这时候就需要用到委托来进行处理.

先说下原理.因为控件处于UI线程.此时调用也处于此线程中.而此时里另一个线程却要赋值,就会造成线程间的混乱.因此.我要建造一个公共地方.让线程间共同使用.

public delegate void getCompute();private void button1_Click(object sender, EventArgs e)        {            Thread th = new Thread(new ThreadStart(StareNewThread));            th.Start();            //getCompute setdeleght = new getCompute(Compute);            //setdeleght.Invoke();            //this.BeginInvoke(new getCompute(Compute));                    }private void StareNewThread()        {            getCompute Getdelegate = new getCompute(Compute);            this.BeginInvoke(Getdelegate);        }private void Compute()        {            int value1 =int.Parse( textBox1.Text);            int value2 = int.Parse(textBox2.Text);            int value = value2 / value1;            textBox2.Text = value.ToString();        }

?

通过委托将函数作为参数传递。待续,以后觉得和线程有用的信息都记录于此,刚开始学习,希望大家一起进步。

热点排行