CWinForm多线程开发剖析
C语言中的多线程编程
![C语言中的多线程编程](https://img.taocdn.com/s3/m/4bb461a1112de2bd960590c69ec3d5bbfd0ada9f.png)
C语言中的多线程编程多线程编程是指在一个程序中同时运行多个线程,这些线程可以并行执行不同的任务,以提高程序的效率和并发性。
在C语言中,可以使用标准的Thread库来实现多线程编程。
下面将介绍C语言中多线程编程的基本概念和用法。
首先,C语言中多线程编程的基本概念是线程。
线程是程序中的一条执行路径,每个线程都有自己的栈空间和寄存器等,可以独立执行不同的任务。
在C语言中,可以使用Thread库中的函数来创建线程、管理线程和同步线程之间的操作。
要在C语言中创建线程,首先需要包含Thread库的头文件,并定义一个函数作为线程的入口点。
然后使用Thread库中的函数创建线程并指定入口点函数,最后启动线程。
例如,下面是一个简单的C语言多线程编程示例:```#include <stdio.h>#include <stdlib.h>#include <pthread.h>void *print_message(void *ptr) {char *message = (char *)ptr;printf("%s\n", message);pthread_exit(NULL);}int main() {pthread_t thread;char *message = "Hello, this is a thread!";pthread_create(&thread, NULL, print_message, (void *)message);pthread_join(thread, NULL);return 0;}```在这个示例中,首先定义了一个print_message函数作为线程的入口点,然后在主函数中创建了一个线程,并指定入口点函数为print_message,最后等待线程执行完毕。
当程序执行时,会输出"Hello, this is a thread!",表示线程成功执行。
C语言多线程编程的基本原理和实战技巧
![C语言多线程编程的基本原理和实战技巧](https://img.taocdn.com/s3/m/95cb825f793e0912a21614791711cc7930b7784c.png)
C语言多线程编程的基本原理和实战技巧随着计算机技术的不断发展,多线程编程在软件开发中变得越来越重要。
多线程编程可以提高程序的执行效率,充分利用多核处理器的优势,同时也能改善用户体验。
C语言作为一种广泛应用的编程语言,也提供了丰富的多线程编程接口和技巧。
一、多线程编程的基本原理多线程编程的基本原理是通过创建多个执行线程来同时执行不同的任务,从而提高程序的并发性和响应性。
在C语言中,我们可以使用pthread库来实现多线程编程。
下面是一个简单的示例代码:```c#include <stdio.h>#include <pthread.h>void* thread_function(void* arg) {printf("Hello from a thread!\n");pthread_exit(NULL);}int main() {pthread_t thread_id;int result = pthread_create(&thread_id, NULL, thread_function, NULL);if (result != 0) {perror("Thread creation failed");return 1;}printf("Hello from the main thread!\n");pthread_join(thread_id, NULL);return 0;}```在上面的代码中,我们创建了一个新的线程,并在该线程中执行thread_function函数。
主线程和新线程可以同时执行不同的任务,并且通过pthread_join函数等待新线程的结束。
二、多线程编程的实战技巧除了基本原理外,还有一些实战技巧可以帮助我们更好地进行多线程编程。
1. 线程同步在多线程编程中,线程之间的并发执行可能会导致数据竞争和不一致的结果。
线程实例实验报告总结
![线程实例实验报告总结](https://img.taocdn.com/s3/m/8db1056cbb1aa8114431b90d6c85ec3a87c28b94.png)
一、实验目的本次实验旨在通过实例操作,深入了解线程的概念、创建、同步与通信机制,以及线程在实际编程中的应用。
通过实验,提高对线程的理解和运用能力,为以后开发多线程程序打下坚实基础。
二、实验环境1. 操作系统:Windows 102. 开发工具:Visual Studio 20193. 编程语言:C#三、实验内容1. 线程的基本概念线程是程序执行的最小单位,是操作系统进行资源分配和调度的基本单位。
线程具有以下特点:(1)线程是轻量级的,创建、销毁线程的开销较小。
(2)线程共享进程的资源,如内存、文件等。
(3)线程之间可以并发执行。
2. 线程的创建在C#中,可以使用以下方式创建线程:(1)使用Thread类```csharpThread thread = new Thread(new ThreadStart(MethodName));thread.Start();```(2)使用lambda表达式```csharpThread thread = new Thread(() => MethodName());thread.Start();```(3)使用匿名方法```csharpThread thread = new Thread(delegate () { MethodName(); });thread.Start();```3. 线程的同步线程同步是指多个线程在执行过程中,为了防止资源冲突而采取的协调机制。
C#提供了以下同步机制:(1)互斥锁(Mutex)```csharpMutex mutex = new Mutex();mutex.WaitOne();// 线程同步代码mutex.ReleaseMutex();```(2)信号量(Semaphore)```csharpSemaphore semaphore = new Semaphore(1, 1);semaphore.WaitOne();// 线程同步代码semaphore.Release();```(3)读写锁(ReaderWriterLock)```csharpReaderWriterLock rwlock = new ReaderWriterLock();rwlock.AcquireReaderLock();// 读取操作rwlock.ReleaseReaderLock();```4. 线程的通信线程通信是指线程之间传递消息、共享数据的过程。
C语言中的多线程编程技术解析
![C语言中的多线程编程技术解析](https://img.taocdn.com/s3/m/37918398b04e852458fb770bf78a6529647d35c1.png)
C语言中的多线程编程技术解析在C语言中,多线程编程技术是一种能够提高程序性能和效率的重要手段。
多线程编程使得程序能够同时执行多个任务,从而充分利用多核处理器的优势,加快程序的运行速度。
本文将从多线程的概念、实现方式以及常见应用场景进行解析,帮助读者深入了解C语言中的多线程编程技术。
首先,我们需要了解多线程的概念。
在C语言中,多线程是指在一个程序中可以同时执行多个程序段或函数,每个线程都有自己的执行路径。
与传统的单线程程序相比,多线程程序能够更好地同时处理多个任务,提高程序的并发性和响应速度。
在多线程编程中,通常会涉及线程的创建、启动、暂停、终止以及线程之间的通信等操作。
接着,我们需要了解多线程在C语言中的实现方式。
在C语言中,可以使用标准的POSIX线程库(pthread)来实现多线程编程。
使用pthread库,我们可以轻松创建、启动和管理多个线程。
具体来说,通过pthread_create函数可以创建一个新线程,通过pthread_join函数可以等待一个线程的结束,通过pthread_exit函数可以终止当前线程等。
此外,pthread库还提供了一系列的同步机制,如互斥锁(mutex)、条件变量(condition variable)等,帮助程序员更好地控制线程的并发访问。
在实际应用中,多线程编程技术通常用于处理需要并行处理的任务,比如网络编程、图像处理、数据分析等。
以网络编程为例,当一个服务器需要同时处理多个客户端的请求时,可以为每个客户端连接创建一个独立的线程,从而实现并发处理。
这样不仅提高了服务器的处理能力,也提高了系统的响应速度。
除了提高程序性能外,多线程编程还有助于代码模块化和复用。
通过将不同的功能模块放置在不同的线程中,可以更好地实现代码的分离和聚合,提高程序的可维护性和可扩展性。
此外,多线程编程还有助于充分利用多核处理器的优势,充分发挥硬件资源的性能。
总的来说,C语言中的多线程编程技术是一种重要的程序设计手段,能够提高程序的性能和效率,提高程序的并发性和响应速度。
c#Winform多线程操作
![c#Winform多线程操作](https://img.taocdn.com/s3/m/588cabd3ac51f01dc281e53a580216fc700a53a5.png)
c#Winform多线程操作主要是对⼀个过程需要的时间很长执⾏时会出现界⾯假死的情况⽅法1:Application.DoEvents(),这种⽅法当你拖动窗体时,界⾯不会假死。
但在你拖动时代码不再执⾏,也就是阻塞了,当你不再控制窗体时会继续执⾏,其实这还是⼀个单线程for (int i = 0; i < 10000; i++){for (int j = 0; j < 100000; j++){textBox1.Text = i.ToString() + "" + j.ToString();Application.DoEvents();}}⽅法2:多线程2.1:取消控件跨线程检测(不推荐有时会出现⼀些莫名奇妙的错误如控件不能加载等问题)2.1.1取消窗体内控件的跨线程检查(单个控件取消也可以) public Form1(){InitializeComponent();CheckForIllegalCrossThreadCalls = false;//⼲掉检测不再检测跨线程}2.1.2新建线程实现跨线程访问///<summary>///新建线程并执⾏///</summary>///<param name="sender"></param>///<param name="e"></param>private void button1_Click(object sender, EventArgs e){ThreadStart thStart = new ThreadStart(Pro);//threadStart委托Thread thread = new Thread(thStart);thread.Priority = ThreadPriority.Highest;thread.IsBackground = true; //关闭窗体继续执⾏thread.Start();}public void Pro(){for (int i = 0; i < 10000; i++){for (int j = 0; j < 100000; j++){textBox1.Text = j.ToString();}}}2.2:主线程中操作(推荐) 2.2.1 不⽤取消跨线程访问///<summary>///新建线程并执⾏///</summary>///<param name="sender"></param>///<param name="e"></param>private void button1_Click(object sender, EventArgs e){ThreadStart thStart = new ThreadStart(Pro);//threadStart委托Thread thread = new Thread(thStart);thread.Priority = ThreadPriority.Highest;thread.IsBackground = true; //关闭窗体继续执⾏thread.Start();}public void Pro(){for (int i = 0; i < 10000; i++){for (int j = 0; j < 100000; j++){if (textBox1.InvokeRequired)//不同线程访问了textBox1.Invoke(new Action<TextBox, string>(SetTxtValue), textBox1, j.ToString());//跨线程了else//同线程直接赋值textBox1.Text = j.ToString();}}}private void SetTxtValue(TextBox txt, string value){txt.Text = value;}注:多个线程同时访问⼀个⽅法时需要锁定public static readonly object obj = new object();public void Pro(){//lock(obj){}=Monitor.Enter(obj) Monitor.Exit(obj)lock (obj){for (int i = 0; i < 10000; i++){for (int j = 0; j < 100000; j++){if (textBox1.InvokeRequired)//不同线程访问了textBox1.Invoke(new Action<TextBox, string>(SetTxtValue), textBox1, j.ToString());//跨线程了else//同线程直接赋值textBox1.Text = j.ToString();}}}}3.窗体与⾃定义类之间的多线程操作(适⽤数据量⼤查询速度慢时让数据在新线程中查询防主线程卡死) 3.1⾃定义类中定义事件,并定义各事件执⾏的步骤⽅法3.2窗体中实现类,并⽣成类各事件,在多线程中执⾏⾃定义类的步骤⽅法3.3 代码3.1public class WeiTuo{public int count { get; set; }public event EventHandler StartEvent;public event EventHandler MidEvent;public event EventHandler EndEvent;public event EventHandler EEvent;public void ExecEvent(){try{using (SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=123;database=oa")){using (SqlDataAdapter adp = new SqlDataAdapter("select * from a", con)){DataTable dt = new DataTable();adp.Fill(dt);StartEvent(dt.Rows.Count, null);for (int i = 0; i < dt.Rows.Count; i++){a ai = new a() {ID = (int)dt.Rows[i]["id"],Code = dt.Rows[i]["cCode"].ToString()} ;MidEvent(ai, null);}EndEvent(dt.Rows.Count, null);}}}catch (Exception e){EEvent(e.Message, null);}}}public class a{public int ID { get; set; }public String Code { get; set; } = "";}View Code3.4 代码3.2private void button6_Click(object sender, EventArgs e){WeiTuo wt = new WeiTuo();wt.StartEvent += Wt_StartEvent;wt.MidEvent += Wt_MidEvent;wt.EndEvent += Wt_EndEvent;wt.EEvent += Wt_EEvent;Thread th = new Thread(wt.ExecEvent);th.Start();}//特殊委托 actionprivate void Wt_StartEvent(object sender, EventArgs e){Action<string> setLVItem = (s) => { listView1.Items.Add(s); };this.Invoke(setLVItem, sender.ToString());}//特殊委托 actionprivate void Wt_MidEvent(object sender, EventArgs e){Action<string> setLVItem = (s) => { listView1.Items.Add(s); };this.Invoke(setLVItem, ((a)sender).Code);}#region委托实现private void Wt_EndEvent(object sender, EventArgs e){this.Invoke(new setLVItem(setEndValue), "成功");}delegate void setLVItem(string s);void setEndValue(string s){MessageBox.Show(s);}#endregionprivate void Wt_EEvent(object sender, EventArgs e){Action<string> ShowBox = (s) => { MessageBox.Show(s); };this.Invoke(ShowBox, sender.ToString());}View Code3.5 结果如下图task任务与thread⼤同⼩异使⽤时尽量少的让控件跨线程可通过ref 或 out 对参数传出检测线程结束再给控件赋值也可⽤task的wait⽅法4 异步回调private void button1_Click(object sender, EventArgs e){Func<int, int, int> Sum = (i, j) =>{Thread.Sleep(3000);return i + j;};listView1.Items.Add("开始");IAsyncResult iar = Sum.BeginInvoke(1, 2, CallbackWhenDone, "我是测试");listView1.Items.Add("over");}private void CallbackWhenDone(IAsyncResult iar){AsyncResult ar = (AsyncResult)iar;Func<int, int, int> f = (Func<int, int, int>)ar.AsyncDelegate;Action<ListView> a = (lv) =>{lv.Items.Add(ar.AsyncState.ToString());lv.Items.Add(f.EndInvoke(iar).ToString());};this.Invoke( a,listView1);}View Code。
C语言多线程编程实战经验分享
![C语言多线程编程实战经验分享](https://img.taocdn.com/s3/m/229cd5a6988fcc22bcd126fff705cc1754275f5b.png)
C语言多线程编程实战经验分享C语言是一种广泛应用于系统编程和嵌入式开发领域的编程语言,具有高效性和灵活性。
在开发过程中,多线程编程是一种常用的技术,能够充分利用多核处理器的优势,提高程序的性能和响应速度。
本文将分享一些C语言多线程编程的实战经验,希望能够帮助读者更好地应用多线程技术。
首先,多线程编程需要注意线程的并发控制。
在多线程环境下,多个线程会同时访问共享的资源,可能会导致数据竞态和死锁等问题。
为了避免这些问题,可以使用互斥锁(mutex)来保护共享资源的访问。
在访问共享资源之前,先加锁,访问完毕后再解锁,确保同一时间只有一个线程可以访问共享资源,从而保证数据的一致性和正确性。
其次,线程间的通信也是多线程编程中需要考虑的重要问题。
线程间可以通过共享内存、消息队列、信号量等机制进行通信。
其中,消息队列是一种常用的通信方式,可以实现生产者和消费者之间的消息传递。
通过使用消息队列,线程之间可以实现解耦,减少直接依赖关系,提高系统的灵活性和可维护性。
另外,线程的同步和异步执行也是多线程编程的关键。
同步执行是指线程按顺序执行,一个线程执行完毕后再执行下一个线程;而异步执行是指线程可以同时执行,不受其他线程的阻塞。
在实际开发中,需要根据具体的需求选择合适的执行方式,以提高程序的效率和性能。
在进行多线程编程时,还需要注意线程的管理和调度。
多线程系统中会存在多个线程,需要合理地管理和调度这些线程,避免出现优先级倒置、饥饿现象等问题。
可以通过设置线程的优先级、调度策略等方式来进行线程的管理,确保系统的稳定性和响应速度。
最后,调试和测试是多线程编程中不可或缺的一步。
由于多线程程序具有一定的复杂性,可能会出现线程死锁、竞态条件等问题,因此需要通过调试和测试来发现和解决这些问题。
可以使用调试工具、日志记录等方式来定位和排查程序中的bug,保证程序的正确性和稳定性。
总之,C语言多线程编程是一项挑战性的任务,需要综合考虑并发控制、线程通信、执行方式、管理调度等方面的问题。
C# WinForm多线程开发
![C# WinForm多线程开发](https://img.taocdn.com/s3/m/570135e8f705cc17552709e2.png)
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下支持的方法。
c#winform多线程的小例子
![c#winform多线程的小例子](https://img.taocdn.com/s3/m/fc1d5b00a31614791711cc7931b765ce05087a64.png)
c#winform多线程的⼩例⼦在⽂本框中输⼊⼀个数字,点击开始累加按钮,程序计算从1开始累计到该数字的结果。
因为该累加过程⽐较耗时,如果直接在UI线程中进⾏,那么当前窗⼝将出现假死。
为了有更好的⽤户体验,程序启动⼀个新的线程来单独执⾏该计算,然后每隔200毫秒读取⼀次累加结果,并把结果显⽰到⽂本框下⽅的label控件中。
同时,程序⽀持取消操作,点击取消累计按钮,程序将取消累加操作,并把当前累加值显⽰到label中。
为了⽅便后⾯的描述,我把UI线程称作主线程,把执⾏累加计算的线程称作⼯作者线程。
该过程有两个关键点:1:如何在⼯作者线程中访问主线程创建的控件;2:如何取消⽐较耗时的计算;为了便于在⼯作者线程中调⽤累加过程,我把它写成⼀个单独⽅法,如下:复制代码代码如下:/// <summary>/// 从1累加到指定的值,为了让该⽅法⽀持取消操作所以需要CancellationToken参数/// </summary>/// <param name="countTo">累加到的指定值</param>/// <param name="ct">取消凭证</param>private void CountTo(int countTo, CancellationToken ct) {int sum = 0;for (; countTo > 0; countTo--) {if (ct.IsCancellationRequested) {break;}sum += countTo;//Invoke⽅法⽤于获得创建lbl_Status的线程所在的上下⽂this.Invoke(new Action(()=>lbl_Status.Text = sum.ToString()));Thread.Sleep(200);}}该⽅法就是⽤于累加数字,它有两个需要注意的地⽅1:⽅法需要传递⼀个CancellationToken参数,⽤于⽀持取消操作(《clr via c# 3版》中把这种⽅式称作协作式取消,也就是说某⼀个操作必须⽀持取消,然后才能取消该操作);2:为了允许⼯作者线程访问主线程创建的lbl_Status控件,我在该线程中使⽤this.Invoke⽅法。
多线程程序c语言
![多线程程序c语言](https://img.taocdn.com/s3/m/0c2310184a73f242336c1eb91a37f111f1850ddf.png)
多线程程序c语言多线程是计算机中的一个概念,它可以让多个线程同步运行,从而加快计算机运行速度,改善性能。
而在C语言中,使用多线程的方法也是被广泛应用于各个领域中的。
本文将为大家详细讲解如何在C语言中创建和管理多线程。
一、线程和进程的概念在C语言中,线程是执行代码的一种方式,它可以用来实现并发和异步编程。
而进程是资源分配的最小单位,每个进程都有自己的地址空间和独立的工作流程。
一个进程可以包含多个线程。
在操作系统的层面,每个线程都是由进程来管理的,由于线程共享进程的地址空间,所以它们之间的数据传递和通信比较方便。
二、多线程的实现方法在C语言中,要实现多线程的功能,需要使用相关的函数库。
其中最常用的函数库是pthread,使用它可以轻松地创建和管理多个线程。
1. 线程的创建线程的创建主要是通过pthread_create函数实现的。
它的原型定义如下:```#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg);```该函数的第一个参数是一个指向线程ID的指针,第二个参数是指向线程属性的指针,第三个参数是线程所要执行的函数,最后一个参数是传递给函数的参数。
调用成功后,会返回0,并将线程ID放到第一个参数所指向的地址中。
```#include <pthread.h>int pthread_cancel(pthread_t thread);```该函数的参数是要撤销的线程ID。
调用成功后,函数会直接将指定的线程终止掉,并释放它所占用的资源。
三、多线程的应用场景在C语言中,多线程的应用场景非常广泛,下面分别介绍几种典型的应用场景:1. 网络编程在网络编程中,要同时处理多个客户端请求,这时使用多线程可以使程序并发执行,效率更高。
C语言多线程编程
![C语言多线程编程](https://img.taocdn.com/s3/m/3ad2124a6d85ec3a87c24028915f804d2a16877a.png)
C语言多线程编程多线程编程是指在一个程序中同时运行多个线程,以实现并行处理任务的能力。
C语言是一种功能强大的编程语言,也可以用来进行多线程编程。
本文将介绍C语言多线程编程的基本概念、使用方法和注意事项。
一、多线程编程概述多线程编程是一种并发编程方式,它可以提高程序的运行效率,使得程序具有更好的响应能力和并行处理任务的能力。
在多线程编程中,程序会同时运行多个线程,每个线程执行不同的任务,这些线程可以共享数据和资源。
二、C语言多线程编程的基本概念1. 线程线程是程序中的执行单元,可以独立执行和调度。
在C语言中,可以通过使用线程库(如pthread库)来创建和管理线程。
线程之间共享同一进程的内存空间,可以访问共享的全局变量和静态变量。
2. 创建线程在C语言中,要创建新的线程,可以使用pthread库提供的函数pthread_create。
该函数的参数包括指向线程标识符的指针、线程属性和一个指向函数的指针,该函数是新线程将要执行的函数。
3. 线程同步在线程编程中,线程之间的执行是并发的,因此可能会出现数据竞争和资源争用的问题。
为了解决这些问题,需要使用线程同步机制,如互斥锁、条件变量等。
互斥锁可以保护共享数据,确保同一时刻只有一个线程能够访问共享数据。
4. 线程退出在线程执行完任务后,可以调用pthread_exit函数来终止线程的执行。
也可以通过在线程函数中使用return语句来终止线程。
三、C语言多线程编程的使用方法1. 引入头文件在使用多线程编程前,需要引入pthread库的头文件。
可以使用以下指令来引入头文件:#include <pthread.h>2. 创建线程要创建线程,需要调用pthread_create函数。
该函数的调用格式如下:int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg);其中,thread参数是一个指向pthread_t类型的指针,用于存储新线程的ID。
C#WinForm实践开发教程》5.多线程编程技术.ppt
![C#WinForm实践开发教程》5.多线程编程技术.ppt](https://img.taocdn.com/s3/m/31c2c2fcac51f01dc281e53a580216fc700a5398.png)
C#WinForm实践开发教程》5.多线程编程技术.ppt5.6线程应用实例综合例题1:通过Process类获取系统进程列表。
运行界面如下图所示:总结线程是在共享内存空间中并发的多道执行路径在C#中,是使用System.Threading命名空间中的Thread类来创建线程的线程优先级可以更改为ThreadPriority枚举中定义的一个值C#中的lock关键字是实现线程同步的一种方法同步的线程称为安全线程除非绝对必要,否则不要创建线程安全的代码,因为添加不必要的锁定会降低性能usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Threa ding;namespaceConsoleThread{classThreadApp{staticintinterval;staticvoidMain(string[]args){//获取用户输入的数字Console.Write("请输入一个数字:");interval=int.Parse(Console.ReadLine());//定义当前主线程线程对象的名字ThreadthisThread=Thread.C urrentThread;="MainThread";//建立新线程对象ThreadStartworkerStart=newThreadStart(DisplayNumbers);ThreadworkerThread=newThread(workerStart);="WorkerThread";workerThread.IsBackground=true;workerThread.Start();//启动新线程//再建立一个线程ThreadStartworkerStart2=newThreadStart(DisplayNumbers);ThreadworkerThread2=newThread(workerStart2);wor="thirdThread";workerThread2.IsBackground=true;workerThread2.Start();//启动新线程DisplayNumbers();//主线程同步进行计数Console.ReadLine();}staticvoidDisplayNumbers(){//获取当前运行线程的Thread对象实例ThreadthisThread=Thread.CurrentThread;Console.WriteLine("线程:"+th+"已开始运行.");//循环计数直到结束,在指定的间隔输出当前计数值for(inti=1;i<=8interval;i++){if(i%interval==0){Console.WriteLine(+":当前计数为"+i);}}Console.WriteLine("线程"++"完成.");}}}usingSystem;usingSystem.Collections.Generic;usingSystem.Text;using System.Threading;namespaceConsoleThread{classThreadApp {staticintinterval;staticvoidMain(string[]args){//获取用户输入的数字Console.Write("请输入一个数字:");interval=int.Parse(Console.ReadLine());//定义当前主线程线程对象的名字ThreadthisThread=Thread.CurrentThread;="MainThread";thisThread.Priority=ThreadPriority.Highest;//建立新线程对象ThreadStartworkerStart=newThreadStart(DisplayNumbers);ThreadworkerThread=newThread(workerStart);="WorkerThread";workerThread.IsBackground=false;workerThread.Priority=ThreadPriority.AboveNormal;workerThread.Start();//启动新线程//再建立一个线程ThreadStartworkerStart2=newThreadStart(DisplayNumbers);ThreadworkerThread2=newThread(workerStart2);="thirdThread";workerThread2.IsBackground=false;workerThread2.Priority=ThreadPriority.Normal;workerThread2.Start();//启动新线程DisplayNumbers();//主线程同步进行计数Console.ReadLine();}staticvoidDisplayNumbers(){//获取当前运行线程的Thread对象实例ThreadthisThread=Thread.CurrentThread;Console.WriteLine("线程:"++"已开始运行.");//循环计数直到结束,在指定的间隔输出当前计数值for(inti=1;i<=8interval;i++){if(i%interval==0){Console.WriteLine(+":当前计数为"+i);}}Console.WriteLine("线程"++"完成.");}}}usingSystem;usingSystem.Threading;//银行帐户类classTestApp{publicstaticvoidMain(){//建立10个线程同时进行交易Thread[]threads=newThread[10];Accountacc=newAccount(1000);for(inti=0;i<10;i++){Threadt=newThread(newThreadStart(acc.DoTransactions));threads[i]=t;}for(inti=0;i<10;i++){threads[i].Start();}Console.ReadLine();}}classAccount{intbalance;//余额Randomr=newRandom();publicAccount(intinitial){balance=initial;}//取钱publicintWithdraw(intamount){if(balance<0)thrownewException("余额为负!");lock(this){if(balance>=amount){Console.WriteLine("原有余额:"+balance);Console.WriteLine("支取金额:-"+amount);balance=balance-amount;Console.WriteLine("现有余额:"+balance);returnamount;}else{return0;//拒绝交易}}}//测试交易publicvoidDoTransactions(){//支取随机的金额100次for(inti=0;i<100;i++){Withdraw(r.Next(1,100));}}}============================两个线程的互相执行过程演示================================== usingSystem;usingSystem.Threading;classA{ staticvoidMain() { Aobj1=newA(); Threadthread1=newThread(newThreadStart(obj1.ff)); ="第一个间隔40ms循环打印线程"; Bobj2=newB();Threadthread2=newThread(newThreadStart(obj2.gg));="第一个间隔100ms循环打印线程";thread2.Start();//thread2.Join();thread1.Start();Console.ReadLine();}privatevoidff(){for(inti=0;i<10;i++){Console.WriteLine(Th+":Currentcountis"+i);Thread.Sleep(40);}}}classB{publicvoidgg(){for(inti=0;i<5;i++){Console.WriteLine(+":add"+i);Thread.Sleep(100);}}}usingSystem;usingSystem.Collections.Generic;ponentM odel;usingSystem.Data;usingSystem.Drawing;usingSystem.Text;usi ngSystem.Windows.Forms;usingSystem.Diagnostics;usingSyste m.Threading;namespaceWindowsApplication1{publicpartialclassForm11:Form{publicForm11(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){listBox1.Items.Clear();listBox1.Items.Add("编号"+""+"名称");//将所有的系统进程显示在列表框中foreach(ProcessainProcess.GetProcesses()){stringname=a.ProcessName;intid=a.Id;listBox1.Items.Add(id.ToString()+""+name);} }}}--------------基于C#语言Windows程序设计第五章、多线程编程技术本章主要内容介绍 5.1计算机线程介绍5.2System.Threading简介5.3线程的优先级与锁技术CONTENT本章学习目标:理解线程的概念理解.NET中线程的属性和方法创建和使用线程理解线程的特点、优点及使用场合同时执行所有任务,时间更少,效率更高人体5.1线程简介读,写一览无遗血液循环在同一时间点执行各项进程编译程序发送/接收邮件打印文件其他操作系统允许计算机同时执行多项操作程序(进程)5.1线程简介程序1程序2线程1线程2线程3线程1线程2线程3单独的执行路径5.1线程简介进程:是应用程序的一个运行例程,是应用程序的一次动态执行过程。
用MFC实现多线程
![用MFC实现多线程](https://img.taocdn.com/s3/m/eb0b879381eb6294dd88d0d233d4b14e85243e0b.png)
用MFC实现多线程MFC(Microsoft Foundation Class)是微软公司提供的C++ 类库,用于开发 Windows 平台上的桌面应用程序。
MFC 提供了许多实用工具,用于简化 Windows 编程任务,包括多线程编程。
在本文中,我们将介绍如何使用 MFC 实现多线程。
多线程编程是指在一个程序中同时执行多个线程,每个线程都有自己的执行流程。
多线程编程可以提高程序的性能和响应速度,特别是在处理大量计算或耗时的任务时。
要在 MFC 中实现多线程,我们可以使用 CWinThread 类来创建和管理线程。
下面是一个简单的示例,演示了如何使用 MFC 创建一个多线程应用程序。
首先,我们需要在MFC应用程序的主类中添加一个成员函数,该函数将被作为线程函数调用。
在这个示例中,我们将创建一个计算从1到100的和的线程。
```cppUINT CalculationThread(LPVOID pParam)int sum = 0;for (int i = 1; i <= 100; i++)sum += i;}CString strResult;strResult.Format(_T("Sum is %d"), sum);AfxMessageBox(strResult);return 0;}```接下来,在应用程序的`InitInstance`函数中创建线程对象并启动线程。
```cppBOOL CMyApp::InitInstance//...//创建线程对象CWinThread* pThread = AfxBeginThread(CalculationThread, NULL);//...return TRUE;```通过调用`AfxBeginThread`函数,我们将线程函数`CalculationThread`和参数指针`NULL`传递给 MFC,以创建一个新的线程。
多线程在WinForm窗体开发中的应用研究
![多线程在WinForm窗体开发中的应用研究](https://img.taocdn.com/s3/m/ca29e775011ca300a6c3903c.png)
多线程在WinForm窗体开发中的应用研究作者:周岚来源:《软件工程》2017年第03期摘要:通常我们使用异步完成许多计算型的耗时操作,取得应用程序运行所需要的部分数据,再将它们绑定在UI中呈现,这个过程由于数据量偏大,窗体会出现“失去响应”的情况,而线程技术的使用可以方便的实现并发执行,提升资源的利用率,提高程序处理效率,解除“假死”这种糟糕的体验。
本文通过对C#多线程技术及委托方法的介绍,分析研究了在WinForm窗体开发中解决假死状态的两种方法,给出实例及相关代码,并对这两种方法的特点进行了总结。
关键词:多线程;假死;委托;BackGroundWorker控件中图分类号:TP311.11 文献标识码:AAbstract:Asynchronous manners are usually adopted to implement lots of time-consuming computing operation,in order to achieve the data required by the application and bind them to be presented in UI.Due to the great amount of data,the form often stops responding.The multi-thread technology can facilitate the implementation of concurrency,promote the resource utilization,improve processing efficiency,and avoid the terrible experience of "suspended animation".Based on the C# multi-thread technology and principal methods,the paper analyzes two solutions to the problems of suspended animation in the WinForm development,provides examples and related code,and summarizes the characteristics of two solutions.Keywords:multi-threading;suspended animation;commission;BackGroundWorker widget1 引言(Introduction)通常我们使用异步完成许多计算型、IO型的复杂、耗时操作,去取得我们的应用程序运行所需要的一部分数据[1]。
C#多线程详解Part.01(UI线程、子线程)
![C#多线程详解Part.01(UI线程、子线程)](https://img.taocdn.com/s3/m/26f7987ba517866fb84ae45c3b3567ec102ddcb8.png)
C#多线程详解Part.01(UI线程、⼦线程)基本概念什么是进程?当⼀个程序开始运⾏时,它就是⼀个进程,进程包括运⾏中的程序和程序所使⽤到的内存和系统资源。
⼀个进程⾄少有⼀个主线程。
什么是线程?线程是程序中的⼀个执⾏流,每个线程都有⾃⼰的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执⾏同样的函数。
什么是多线程?多线程是指程序中包含多个执⾏流,即在⼀个程序中可以同时运⾏多个不同的线程来执⾏不同的任务,也就是说允许单个程序创建多个并⾏执⾏的线程来完成各⾃的任务。
多线程的好处?可以提⾼ CPU 的利⽤率。
在多线程程序中,⼀个线程必须等待的时候,CPU 可以运⾏其它的线程⽽不是等待,这样就⼤⼤提⾼了程序的效率。
多线程的不利⽅⾯?线程也是程序,所以线程需要占⽤内存,线程越多占⽤内存也越多。
多线程需要协调和管理,所以 CPU 需要花时间来跟踪线程。
线程之间对共享资源的访问会相互影响,必须解决竞⽤共享资源的问题。
线程太多会导致控制太复杂,最终可能造成很多 Bug。
static void Main(string[] args){ = "It's Main Thread";Console.WriteLine( + " [Status:" + Thread.CurrentThread.ThreadState + "]");}通过 Thread 类的静态属性 CurrentThread 可以获取当前正在执⾏的线程。
不管创建了多少个这个类的实例,但是类的静态属性在内存中只有⼀个。
很容易理解 CurrentThread 为什么是静态的--虽然有多个线程同时存在,但是在某⼀个时刻,CPU 只能执⾏其中⼀个!在.net framework class library 中,所有与多线程机制应⽤相关的类都是放在System.Threading命名空间中。
C语言多线程编程了解多线程编程的基本概念和使用方法
![C语言多线程编程了解多线程编程的基本概念和使用方法](https://img.taocdn.com/s3/m/5b19d12a5e0e7cd184254b35eefdc8d376ee1417.png)
C语言多线程编程了解多线程编程的基本概念和使用方法C语言多线程编程:了解多线程编程的基本概念和使用方法在现代计算机领域,多线程编程已经成为了一种常见且重要的技术。
多线程编程可以使程序同时执行多个任务,提高系统的资源利用率和运行效率。
在C语言中,通过使用多线程库和相关的函数,我们可以轻松地实现多线程编程。
本文将介绍多线程编程的基本概念和使用方法。
一、多线程编程概述多线程编程是指在一个程序中同时运行多个线程,每个线程独立执行各自的任务。
与单线程程序相比,多线程程序能够更好地利用系统资源,提高运行效率,提供更好的用户体验。
多线程编程中,程序中的每个线程都拥有自己的执行路径和执行状态,它们可以同时运行,互不干扰。
通过合理地设计和管理线程,可以有效地实现并行处理,提高程序的响应速度。
二、多线程编程的基本概念1. 线程线程是操作系统中最小的执行单元,是程序中独立执行的路径。
C语言中通过多线程库提供的函数来创建和管理线程。
2. 同步在多线程编程中,不同的线程可能会共享同一资源。
同步机制用于控制线程对共享资源的访问,以避免多个线程同时对同一资源进行写操作,造成数据混乱或错误。
3. 互斥互斥是一种常用的同步机制,通过互斥锁(Mutex)来保证在同一时间只有一个线程能够对共享资源进行写操作。
线程在执行对共享资源的访问前,会先请求互斥锁,如果获取成功则执行操作,获取失败则等待。
4. 条件变量条件变量是多线程编程中用于线程间通信的一种机制。
通过条件变量,线程可以等待特定的条件发生,或者唤醒等待某个条件的线程。
三、多线程编程的使用方法1. 多线程库C语言提供了一些多线程编程库,如pthread库。
在使用多线程编程前,需要先引入对应的库文件,并链接相关的函数。
2. 创建线程使用多线程库提供的函数,可以方便地创建新线程并指定其执行函数。
线程执行的函数可以是已经存在的函数,也可以是自行定义的函数。
3. 锁和互斥在多线程编程中,为了保证共享资源的正确性,需要使用互斥锁来同步线程对资源的访问。
c#多线程操作WindowsForms控件
![c#多线程操作WindowsForms控件](https://img.taocdn.com/s3/m/47c2be06773231126edb6f1aff00bed5b9f3734b.png)
public void Test() { this.BeginInvoke(new add(dd)); }
public void dd();//委托方法 { this.textBox1.Text = "AA"; }
这样就可以实现。
当然委托和委托方法可以再设计一下,可以输入一个参数。修改后的代码如下:
delegate void add(string input);
private void button1_Click(object sender, EventArgs e) {
Thread thread = new Thread(new ThreadStart(Test)); thread.Start(); } public void Test() { this.BeginInvoke(new add(dd),new object[]{"我晕死了,原来这样啊"});//注意第二个参数,委托方法的参数就是在这个地方输入。委托方法中不用转换 就直接是字符串了 }
public void dd(string input) {
this.textBox1.Text = input; }
再附加一个写listbox的例子。就是开启一个线程以后在listbox中写入累加的数字
//声明线程对象
System.Threading.Thread thread1 = null;
//创建线程并开启
thread1 = new Thread(startThread1); thread1.IsBackground = true; thread1.Start();
//创建委托对象
delegate void AddList(object o); //委托用的方法
C#窗体WinForm进程,线程
![C#窗体WinForm进程,线程](https://img.taocdn.com/s3/m/a0730217c381e53a580216fc700abb68a982ad7c.png)
C#窗体WinForm进程,线程⼀、进程进程是⼀个具有独⽴功能的程序关于某个数据集合的⼀次运⾏活动。
它可以申请和拥有系统资源,是⼀个动态的概念,是⼀个活动的实体。
Process 类,⽤来操作进程。
命名空间:using System.Diagnostics;Process.Start("calc"); //打开计算器Process.Start("mspaint"); //打开画图Process.Start("iexplore" , ""); //打开浏览器并指定地址(⼀)通过⼀个进程,打开指定的⽂件:1.创建进程对象Process p = new Process();2.创建⼀个StartInfo对象,是指定带盘符的路径。
ProcessStartInfo psi = new ProcessStartInfo(@"C:\user\.....);3.进程指定及开始p.StartInfo = psi; //指定路径p.Start(); //开始进程(⼆)通过⽂件选择框让⽤户⾃⼰选择所需要打开的程序并打开:private void button1_Click(object sender, EventArgs e){//这是选择⽂件的类型openFileDialog1.Filter = "应⽤程序|*.exe";//显⽰对话框并且判断⽤户有没有选中⽂件if (openFileDialog1.ShowDialog() == DialogResult.OK){//取⽂件路径string path = openFileDialog1.FileName;//创建⼀个新的进程Process p = new Process();//制造进程的启动信息ProcessStartInfo psf = new ProcessStartInfo(path);//设置该进程的执⾏信息p.StartInfo = psf;//启动进程p.Start();}}例⼦:注销//这个path就是你要调⽤的exe程序的绝对路径string path = Application.StartupPath;//获取⾃⾝exe或dll的⽂件名路径string s = System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName;private void button2_Click(object sender, EventArgs e){//打开该程序//取该程序⽂件的路径//string path = Application.StartupPath;string path = System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName;//造⼀个进程Process p = new Process();//造⼀个进程的启动信息ProcessStartInfo ps = new ProcessStartInfo(path);//设置进程启动信息p.StartInfo = ps;//启动进程p.Start();//关闭程序this.Close();}例:窗⼝实现⿏标拖动private int x;private int y;private void pictureBox1_MouseDown(object sender, MouseEventArgs e){//⿏标点击时的XY坐标x = e.X;y = e.Y;}private void pictureBox1_MouseMove(object sender, MouseEventArgs e){//判断⿏标按下的是左键if (e.Button == System.Windows.Forms.MouseButtons.Left){//边距=当前的距离+移动的距离this.Left = this.Left+(e.X - x);this.Top = this.Top +(e.Y - y);}}⼆、线程线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执⾏流的最⼩单元。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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以后就已经是一种错误的方法了。
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片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的,也就是说无论我们在项目的什么地方修改了这个值,他就会在全局起作用。
而且像这种跨线程访问是否存在异常,我们通常都会去检查。
如果项目中其他人修改了这个属性,那么我们的方案就失败了,我们要采取另外的方案。
第二种方案[csharp] view plain copy 在CODE上查看代码片派生到我的代码片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多线程控件的控制了。
二ThreadPool 与Timer本文接上文,继续探讨WinForm中的多线程问题,再次主要探讨threadpool 和timer。
一、ThreadPool线程池(ThreadPool)是一种相对较简单的方法,它适应于一些需要多个线程而又较短任务(如一些常处于阻塞状态的线程),它的缺点是对创建的线程不能加以控制,也不能设置其优先级。
由于每个进程只有一个线程池,当然每个应用程序域也只有一个线程池(对线),所以你将发现ThreadPool类的成员函数都为static!当你首次调用ThreadPool.QueueUserWorkItem、ThreadPool.RegisterWaitForSingleObject等,便会创建线程池实例。
下面我就线程池当中的两函数作一介绍:[csharp] view plain copy 在CODE上查看代码片派生到我的代码片public static bool QueueUserWorkItem( //调用成功则返回trueWaitCallback callBack,//要创建的线程调用的委托object state //传递给委托的参数)//它的另一个重载函数类似,只是委托不带参数而已此函数的作用是把要创建的线程排队到线程池,当线程池的可用线程数不为零时(线程池有创建线程数的限制,缺身值为25),便创建此线程,否则就排队到线程池等到它有可用的线程时才创建。
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject,// 要注册的WaitHandleWaitOrTimerCallback callBack,// 线程调用的委托object state,//传递给委托的参数int TimeOut,//超时,单位为毫秒,bool executeOnlyOnce //是否只执行一次);public delegate void WaitOrTimerCallback(object state,//也即传递给委托的参数bool timedOut//true表示由于超时调用,反之则因为waitObject);此函数的作用是创建一个等待线程,一旦调用此函数便创建此线程,在参数waitObject变为终止状态或所设定的时间TimeOut到了之前,它都处于“阻塞”状态,值得注意的一点是此“阻塞”与Thread的WaitSleepJoin状态有很大的不同:当某Thread处于WaitSleepJoin 状态时CPU会定期的唤醒它以轮询更新状态信息,然后再次进入WaitSleepJoin状态,线程的切换可是很费资源的;而用此函数创建的线程则不同,在触发它运行之前,CPU不会切换到此线程,它既不占用CPU的时间又不浪费线程切换时间,但CPU又如何知道何时运行它?实际上线程池会生成一些辅助线程用来监视这些触发条件,一旦达到条件便启动相应的线程,当然这些辅助线程本身也占用时间,但是如果你需创建较多的等待线程时,使用线程池的优势就越加明显。
更详细内容demo:[csharp] view plain copy 在CODE上查看代码片派生到我的代码片namespace TestMethodInvoker{public partial class Form2 : Form{public Form2(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){//ThreadPool.RegisterWaitForSingleObject(// ev,// new WaitOrTimerCallback(WaitThreadFunc),// 4,// 2000,// false//表示每次完成等待操作后都重置计时器,直到注销等待// );ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunc), "test1");//Thread.Sleep(10000);}private delegate void MyInvokeDelegate(string name);private void Test(object o){richTextBox1.Text += string.Format("the object is {0} \n", o);}public void ThreadFunc(object b){this.Invoke(new MyInvokeDelegate(Test), b);}public void WaitThreadFunc(object b, bool t){richTextBox1.Text += string.Format("the object is {0},t is {1}\n", b, t);}}}一个很值得扩展的地方时,这里的invoke 用的是代理,其实还有其他的方法,比如action 和func。