[择要]本文引见C# WinForm多线程开辟之Thread类库,并供应简朴的示例代码供参考。
Windows是一个多使命的体系,假如你运用的是windows 2000及其以上版本,你能够经由过程使命治理器检察当前体系运转的顺序和历程。什么是历程呢?当一个顺序最先运转时,它就是一个历程,历程所指包括运转中的顺序和顺序所运用到的内存和体系资源。而一个历程又是由多个线程所构成的,线程是顺序中的一个实行流,每一个线程都有本身的专有寄存器(栈指针、顺序计数器等),但代码区是同享的,即差别的线程能够实行一样的函数。多线程是指顺序中包括多个实行流,即在一个顺序中能够同时运转多个差别的线程来实行差别的使命,也就是说许可单个顺序建立多个并行实行的线程来完成各自的使命。
一 关于Thread的申明
在.net framework class library中,一切与多线程机制运用相干的类都是放在System.Threading定名空间中的。个中供应Thread类用于建立线程,ThreadPool类用于治理线程池等等,别的还供应处理了线程实行部署,死锁,线程间通信等实际题目的机制。假如你想在你的运用顺序中运用多线程,就必须包括这个类。Thread类有几个至关重要的要领,形貌以下:
Start():启动线程
Sleep(int):静态要领,停息当前线程指定的毫秒数
Abort():一般运用该要领来住手一个线程
Suspend():该要领并不住手未完成的线程,它仅仅挂起线程,今后还可恢复。
Resume():恢复被Suspend()要领挂起的线程的实行
线程进口使顺序知道该让这个线程干什么事,在C#中,线程进口是经由过程ThreadStart代办(delegate)来供应的,你能够把ThreadStart理解为一个函数指针,指向线程要实行的函数,当挪用 Thread.Start()要领后,线程就最先实行ThreadStart所代表或许说指向的函数。 ThreadState在种种情况下的能够取值以下:
Aborted:线程已住手
AbortRequested:线程的Thread.Abort()要领已被挪用,然则线程还未住手
Background:线程在背景实行,与属性Thread.IsBackground有关
Running:线程正在一般运转
Stopped:线程已被住手
StopRequested:线程正在被请求住手
Suspended:线程已被挂起(此状况下,能够经由过程挪用Resume()要领从新运转)
SuspendRequested:线程正在请求被挂起,然则未来得及相应
Unstarted:未挪用Thread.Start()最先线程的运转
WaitSleepJoin:线程由于挪用了Wait(),Sleep()或Join()等要领处于封闭状况
二 Winform中运用的thread
起首能够看看最直接的要领,也是.net 1.0下支撑的要领。但请注意的是,此要领在.net 2.0今后就已是一种毛病的要领了。
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Thread thread = new Thread(ThreadFuntion); thread.IsBackground = true; thread.Start(); } private void ThreadFuntion() { while (true) { this.textBox1.Text = DateTime.Now.ToString(); Thread.Sleep(1000); } } }
这段code 在vs2005或许2008上都抛出非常 :Cross-thread operation not valid:Control 'textBox1' accessed from a thread other than the thread it was created on . 这是由于.net 2.0今后加强了平安机制,不许可在winform中直接跨线程接见控件的属性。那末怎样处理这个题目呢,下面供应几种计划。
第一种计划: 在Thread建立之气,将Control.CheckForIllegalCrossThreadCalls 设为 false。 此代码通知编译器:在这个类中我们不搜检跨线程的挪用是不是正当(假如没有加这句话运转也没有非常,那末申明体系以及默许的采用了不搜检的体式格局)。但是,这类要领不可取。我们检察CheckForIllegalCrossThreadCalls 这个属性的定义,就会发明它是一个static的,也就是说不管我们在项目的什么地方修改了这个值,他就会在全局起作用。而且像这类跨线程接见是不是存在非常,我们一般都会去搜检。假如项目中其他人修改了这个属性,那末我们的计划就失利了,我们要采用别的的计划。
第二种计划
namespace TestInvoker { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(StartSomeWorkFromUIThread)); thread.IsBackground = true; thread.Start(); //StartSomeWorkFromUIThread(); //label1.Text = "Set value through another thread!"; } private void StartSomeWorkFromUIThread() { if (this.InvokeRequired) { BeginInvoke(new EventHandler(RunsOnWorkerThread), null); } else { RunsOnWorkerThread(this, null); } } private void RunsOnWorkerThread(object sender, EventArgs e) { Thread.Sleep(2000); label1.Text = System.DateTime.Now.ToString(); } } }
经由过程上叙代码,能够看到题目已被处理了,经由过程守候异步,我们就不会老是持有主线程的掌握,如许就能够在不发生跨线程挪用非常的情况下完成多线程对winform多线程控件的掌握了。
以上就是C# WinForm多线程开辟(一) Thread类库的内容,更多相干内容请关注ki4网(www.ki4.cn)!