您好,欢迎访问一九零五行业门户网

C# WinForm多线程开发(二) ThreadPool 与 Timer

原文地址:点击打开链接
[摘要]本文介绍c# winform多线程开发之threadpool 与 timer,并提供详细的示例代码供参考。
本文接上文,继续探讨winform中的多线程问题,再次主要探讨threadpool 和timer。
一 、threadpool线程池(threadpool)是一种相对较简单的方法,它适应于一些需要多个线程而又较短任务(如一些常处于阻塞状态的线程),它的缺点是对创建的线程不能加以控制,也不能设置其优先级。由于每个进程只有一个线程池,当然每个应用程序域也只有一个线程池(对线),所以你将发现 threadpool类的成员函数都为static!当你首次调用threadpool.queueuserworkitem、 threadpool.registerwaitforsingleobject等,便会创建线程池实例。下面我就线程池当中的两函数作一介绍:
public static bool queueuserworkitem( //调用成功则返回true waitcallback callback,//要创建的线程调用的委托 object state //传递给委托的参数 )//它的另一个重载函数类似,只是委托不带参数而已
此函数的作用是把要创建的线程排队到线程池,当线程池的可用线程数不为零时(线程池有创建线程数的限制,缺身值为25),便创建此线程,否则就排队到线程池等到它有可用的线程时才创建。
public static registeredwaithandle registerwaitforsingleobject( waithandle waitobject,// 要注册的 waithandle waitortimercallback 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:
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。实例代码如下:
this.invoke(new action<string>(this.changetext), o.tostring()); this.invoke(new action(delegate() { this.textbox1.text = o.tostring();})); private void dosomething(object o) { system.func<string, int> f = new func<string, int>(this.getid); object result = this.invoke(f, o.tostring()); messagebox.show(result.tostring()); } private int getid(string name) { this.textbox1.text = name; if (name == "y") { return 999; } else { return 0; } }
二、 timer
它适用于需周期性调用的方法,它不在创建计时器的线程中运行,它在由系统自动分配的单独线程中运行。这和win32中的settimer方法类似。它的构造为:
public timer( timercallback callback,//所需调用的方法 object state,//传递给callback的参数 int duetime,//多久后开始调用callback int period//调用此方法的时间间隔 );//
如果 duetime 为0,则 callback 立即执行它的首次调用。如果 duetime 为 infinite,则 callback 不调用它的方法。计时器被禁用,但使用 change 方法可以重新启用它。如果 period 为0或 infinite,并且 duetime 不为 infinite,则 callback 调用它的方法一次。计时器的定期行为被禁用,但使用 change 方法可以重新启用它。如果 period 为零 (0) 或 infinite,并且 duetime 不为 infinite,则 callback 调用它的方法一次。计时器的定期行为被禁用,但使用 change 方法可以重新启用它。
在创建计时器之后若想改变它的period和duetime,我们可以通过调用timer的change方法来改变:
public bool change( int duetime, int period );//
显然所改变的两个参数对应于timer中的两参数。
以上就是c# winform多线程开发(二) threadpool 与 timer的内容。
其它类似信息

推荐信息