最近在学习线程相关的内容,所以把学习过程中的心得记录下来,相信大家常用

ThreadPool.QueueUserWorkItem()或者Thread thd=new Thread(new ThreadStart(test)))但是应该很少人知道用ThreadPool.RegisterWaitForSingleObject(高手除外啦),我也是最近才知道。让我来给各位看官解释一下它的用法吧,首先我们看一下它的原型:

Code
public static RegisteredWaitHandle RegisterWaitForSingleObject(
    WaitHandle waitObject,
    WaitOrTimerCallback callBack,
    Object state,
    int millisecondsTimeOutInterval,
    bool executeOnlyOnce
)

它的参数说明如下:

Parameters

waitObject
Type: System.Threading..::.WaitHandle

The WaitHandle to register. Use a WaitHandle other than Mutex.

callBack
Type: System.Threading..::.WaitOrTimerCallback

The WaitOrTimerCallback delegate to call when the waitObject parameter is signaled.

state
Type: System..::.Object

The object that is passed to the delegate.

millisecondsTimeOutInterval
Type: System..::.Int32

The time-out in milliseconds. If the millisecondsTimeOutInterval parameter is 0 (zero), the function tests the object's state and returns immediately. If millisecondsTimeOutInterval is -1, the function's time-out interval never elapses.

executeOnlyOnce
Type: System..::.Boolean

true to indicate that the thread will no longer wait on the waitObject parameter after the delegate has been called; false to indicate that the timer is reset every time the wait operation completes until the wait is unregistered.

Return Value

Type: System.Threading..::.RegisteredWaitHandle

The RegisteredWaitHandle that encapsulates the native handle.

相信看了这些之后大家还是一头雾水,这个方法的做用是向线程池添加一个可以定时执行的方法,第四个参数millisecondsTimeOutInterval 就是用来设置间隔执行的时间,但是这里第五个参数executeOnlyOnce 会对第四个参数起作用,当它为true时,表示任务仅会执行一次,就是说它不会,像Timer一样,每隔一定时间执行一次,这个功能的话用Timer控件也可以实现

该方法还在此基础上提供了基于信号量来触发执行任务。

信号量也叫开关量,故名思议,它只有两种状态,不是true就是false,

WaitHandle就是这类开关量的基础类,继承它的类有Mutex,ManualResetEvent,AutoResetEvent,一般我们使用后两个

写法:

Code
        static ManualResetEvent wait2=new ManualResetEvent(false);
        static AutoResetEvent wait=new AutoResetEvent(false);

我们可以在将其实例化时指定开关量的初始值。(true为有信号,false为没信号)

ManualResetEvent和AutoResetEvent的区别在于:

前者调用Set方法后将自动将开关量值将一直保持为true,后者调用Set方法将变为true随后立即变为false,可以将它理解为一个脉冲。

我们来看几个例子

例子一:实现一个普通的定时器

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace test
{
    class Class14
    {
        static AutoResetEvent wait=new AutoResetEvent(false);
        static void Main(string[] args)
        {
            object state=new object();
            ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(test11), state,5000, false);
            Console.ReadKey();
        }

private static void test11(object state, bool timedOut)
        {
                Console.WriteLine("aaa");
        }
    }
}

例子二,使用开关量提前执行下一次任务执行的时间为立即执行(有点绕,就是说原先间隔10s执行下一次任务,但是使用了开关量的set方法,立即执行下一次的任务,执行的时间提前了,下一次执行的时间又重新开始算

在这里请注意一个细节,下面的代码中当我们向线程池中注册任务的语句即            ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(test11), state,5000, false);
它是间隔5秒执行,当刚加入线程池后它是需要过了5秒后才会第一次执行回调函数的,也就是说不是一加入第0秒就会执行一次回调函数的。这里使用了一个wait.Set()方法使得立即执行了回调函数而不需要等待5秒钟,所以输出结果的第一个“aaa”是由wait.Set()操作引起的。

如果我们不使用wait.Set(),而是将AutoResetEvent wait=new AutoResetEvent(true)的初始值改为true也会在第0秒输出“aaa”

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace test
{
    class Class14
    {
        static ManualResetEvent wait2=new ManualResetEvent(false);
        static AutoResetEvent wait=new AutoResetEvent(false);
        static void Main(string[] args)
        {
            object state=new object();
            ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(test11), state,5000, false);
            wait.Set();
            Console.ReadKey();
        }

private static void test11(object state, bool timedOut)
        {
                Console.WriteLine("aaa");
        }
    }
}

第三个例子:使用ManualResetEvent,这个例子有点意思,它会不停的输出"aaa",为什么?

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace test
{
    class Class14
    {
        static ManualResetEvent wait=new ManualResetEvent(true);
        static void Main(string[] args)
        {
            object state=new object();
            ThreadPool.RegisterWaitForSingleObject(wait, new WaitOrTimerCallback(test11), state,5000, false);

Console.ReadKey();
        }

private static void test11(object state, bool timedOut)
        {
                Console.WriteLine("aaa");
        }
    }
}

因为ManualResetEvent会一值保持开关量为true,所以会一直触发执行回调函数,

关于ThreadPool.RegisterWaitForSingleObject和WaitHandle的应用介绍相关推荐

  1. C#多线程编程介绍——使用thread、threadpool、timer

    C#多线程编程介绍--使用thread.threadpool.timer 在system.threading 命名空间提供一些使得能进行多线程编程的类和接口,其中线程的创建有以下三种方法:thread ...

  2. ThreadPool基础之RegisterWaitForSingleObject

    首先我们看一下它的原型: public static RegisteredWaitHandle RegisterWaitForSingleObject(      WaitHandle waitObj ...

  3. C#并行开发_Thread/ThreadPool, Task/TaskFactory, Parallel

    大家好,本次讨论的是C#中的并行开发,给力吧,随着并行的概念深入,哥也赶上这个潮流了,其实之前讨论C#的异步调用或者C#中BeginInvoke或者Invoke都已经涉及了部分本篇的内容. 参考书目: ...

  4. 稳扎稳打Silverlight(25) - 2.0线程之Thread, Timer, BackgroundWorker, ThreadPool

    [索引页] [源码下载] 稳扎稳打Silverlight(25) - 2.0线程之Thread, Timer, BackgroundWorker, ThreadPool 作者:webabcd 介绍 S ...

  5. 第三节:ThreadPool的线程开启、线程等待、线程池的设置、定时功能

    一. ThreadPool简介 ThreadPool简介:ThreadPool是一个线程池,当你需要开启n个线程时候,只需把这个指令抛给线程池,它将自动分配线程进行处理,它诞生于.Net 2.0时代. ...

  6. ThreadPool的线程开启、线程等待、线程池的设置、定时功能

    一. ThreadPool简介 ThreadPool简介:ThreadPool是一个线程池,当你需要开启n个线程时候,只需把这个指令抛给线程池,它将自动分配线程进行处理,它诞生于.Net 2.0时代. ...

  7. .NET多线程编程入门

    在.NET多线程编程这个系列我们讲一起来探讨多线程编程的各个方面.首先我将在本篇文章的开始向大家介绍多线程的有关概念以及多线程编程的基础知识;在接下来的文章中,我将逐一讲述.NET平台上多线程编程的知 ...

  8. Thread concepts

    多任务和多线程 在.NET多线程编程这个系列我们讲一起来探讨多线程编程的各个方面.首先我将在本篇文章的开始向大家介绍多线程的有关概念以及多线程编程的基础知识;在接下来的文章中,我将逐一讲述.NET平台 ...

  9. CLR Via C# 3rd 阅读摘要 -- Chapter 28 – Primitive Thread Synchronization Constructs

    Class Libraries and Thread Safety 线程同步是用来避免多个线程同时访问共享数据时出现冲突: 线程同步的障碍: 1.极其乏味易错: 2.锁严重影响性能: 3.线程同步锁在 ...

最新文章

  1. 在ROS中开始自主机器人仿真 - 2 让turtlebot跑起来
  2. ulimit限制 新系统_系统限制ulimit学习
  3. JavaScript id_好程序员web前端分享Javascript中函数作为对象
  4. 深度学习:又一次推动AI梦想(Marr理论、语义鸿沟、视觉神经网络、神经形态学)
  5. 在java.library.path中找不到允许在生产环境中实现最佳性能的基于APR的Apache Tom.....
  6. php内核分析(六)-opcode
  7. 【C++基础】模板基础与函数模板
  8. Php通过gsoap调用c++ websevice
  9. 同一master,两个slave的server_id相同问题处理
  10. java 读取文件 二进制_JAVA中读取文件(二进制,字符)内容的几种方法总结
  11. php 背单词系统_《PHP 编程词典(珍藏版)》
  12. swift语言 数组定义_如何在Swift中声明弱引用数组?
  13. Python+OpenCV:色彩空间转换
  14. Postman中json内字符串转义问题
  15. 2021-10-12 CHIP类PCB封装的创建
  16. 【AI大咖】扒一下低调的Yoshua Bengio大神
  17. 牛客--两种排序方法
  18. 办理ICP证、SP证、BBS证及非经营性网站(ICP)备案常见问题解答
  19. SQL中的declare用法
  20. JAVA:List复制

热门文章

  1. [数据库]SQL Server 用户NT AUTHORITY\IUSR 登录失败
  2. DB2数据库中DB2字符串类型
  3. PostgreSQL连接问题(Net LO problem)
  4. WEB交互的划时代革新--HTML5中WebSocket应用【1】
  5. 共享存储及SAN(iscsi)配置
  6. linux 树型显示文件 tree ls tree 命令
  7. php 计算本月第一天 本月最后一天 下个月第一天
  8. LinkedList 实现原理及源码解析(jdk8 底层⽤的是链表)
  9. Spring Cloud 微服务实战系列-Spring Boot再次入门(二)
  10. qemu-kvm命令行参数