C# WinForm多线程开发(二) ThreadPool 与 Timer-阿里云开发者社区

开发者社区> jiankunking> 正文

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

简介: 原文地址:点击打开链接 [摘要]本文介绍C# WinForm多线程开发之ThreadPool 与 Timer,并提供详细的示例代码供参考。 本文接上文,继续探讨WinForm中的多线程问题,再次主要探讨threadpool 和timer。 一 、ThreadPool 线程池(ThreadPool)是一种相对较简单的方法,它适应于一些需要多个线程而又较短任务(如一些常
+关注继续查看

原文地址:点击打开链接

[摘要]本文介绍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中的两参数。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
西门子Softnet驱动的成功开发
前段时间用西门子提供的Prodave5.5开发了基于YFIOServer的驱动程序,很可惜以太网方式它不支持,所以只好用西门子的softnet来开发相应的驱动了
438 0
C# WinForm多线程开发(三) Control.Invoke
原文地址:点击打开链接 [摘要]本文介绍C# WinForm多线程开发之Control.Invoke,并提供详细的示例代码供参考。 下面我们就把在Windows Form软件中使用Invoke时的多线程要注意的问题给大家做一个介绍。 首先,什么样的操作需要考虑使用多线程?总的一条就是,负责与用户交互的线程(以下简称为UI线程)应该保持顺畅,当UI线程调用的API可能引
1595 0
20.Eclipse下Ndk开发(pthread开启线程调用Java方法)
本项目最终的目的是在pthread线程中,调用Java一个工具类得到多个uuid,然后调用类中另一个方法弹出toast,实现在c中获取安卓上下文对象Context 编译native方法,生成头文件的一系列过程不再赘述,直接上代码,都在注释中 PosixUtils: package com.
987 0
【Android NDK 开发】JNI 线程 ( JNI 线程创建 | 线程执行函数 | 非 JNI 方法获取 JNIEnv 与 Java 对象 | 线程获取 JNIEnv | 全局变量设置 )
【Android NDK 开发】JNI 线程 ( JNI 线程创建 | 线程执行函数 | 非 JNI 方法获取 JNIEnv 与 Java 对象 | 线程获取 JNIEnv | 全局变量设置 )
15 0
Java 并发/多线程教程(三)-多线程的开销
        本系列译自jakob jenkov的Java并发多线程教程,个人觉得很有收获。由于个人水平有限,不对之处还望矫正!     应用程序由单线程到多线程,不仅仅给我带来了便利,同时也也带来了一些开销。
878 0
C#线程访问winform窗体控件
参考地址:http://www.cnblogs.com/jason-liu-blogs/archive/2012/09/08/2677008.html 添加: public Form() { InitializeComponent(); Control.
590 0
如何让您的php也支持pthreads多线程
  我们常常会碰到这样一种情况,开发环境在windows下开发,而生产环境确是linux。windows下能正常运行,上传到linux后却无法好好地玩耍了。然后开始了一轮尼玛式的疯狂的查找原因,最后发现是服务器环境问题。
1076 0
+关注
726
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载