`
mlzboy
  • 浏览: 724697 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

阅读更多

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

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

 

Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->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
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->        static ManualResetEvent wait2=new ManualResetEvent(false);
        
static AutoResetEvent wait=new AutoResetEvent(false);

 

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

ManualResetEvent和AutoResetEvent的区别在于:

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

我们来看几个例子

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

Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->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,5000false);
            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
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->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,5000false);
            wait.Set();
            Console.ReadKey();
        }

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

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

 

Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->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,5000false);

            Console.ReadKey();
        }

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

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

 

分享到:
评论

相关推荐

    threadpool.tar.gz

    在C++编程中,线程池是一种用于管理并发任务的技术,它通过预先创建一组线程来处理任务,而不是为每个任务创建一个新的线程。在"threadpool.tar.gz...通过理解和应用这些概念,开发者可以创建高效、可扩展的并发程序。

    ThreadPool.zip

    ThreadPool.zip这个压缩包文件包含了一系列关于线程池和内存池技术的实现,主要适用于Linux操作系统。线程池和内存池是提高系统效率和资源管理的关键技术,在多线程编程和大规模数据处理中尤为常见。 线程池是一种...

    C#线程池 所有线程运行完毕

    6. **线程池的配置**:可以通过`ThreadPool.GetMaxThreads`和`ThreadPool.SetMaxThreads`来获取和设置线程池的最大线程数。同时,也可以通过`ThreadPool.GetMinThreads`和`ThreadPool.SetMinThreads`设置最小线程数...

    threadpool.h

    c++11封装的项目中使用的线程池,lambda作为线程函数,可以使用任意形式的线程回调函数。单例模式。欢迎下载,评论

    threadpool.rar

    在"threadpool.rar"压缩包中,我们看到的是一个C语言实现的线程池实例,这对于理解和掌握线程池工作原理及其在C语言中的应用非常有帮助。 线程池的工作机制主要包括以下几个关键部分: 1. **线程池初始化**:在...

    Linux_thread_pool.zip_linux_linux threadpool.cpp_linux 多线程_linux

    `Linux_thread_pool.zip`中的`linux_threadpool.cpp`文件就是一个关于Linux线程池实现的示例,对于学习Linux下多线程编程具有很高的参考价值。 首先,让我们理解什么是线程池。线程池是由一组预先创建的线程组成的...

    资源池等待所有线程执行完毕的方法

    `ThreadPool.RegisterWaitForSingleObject`方法允许注册一个等待句柄,该句柄会在指定的对象状态变为信号状态时被触发。下面是如何使用此方法来等待所有线程执行完毕的一个示例: ```csharp using System.Threading...

    c# 线程池的管理 通过ThreadPool

    3. **MaxThreads与MinThreads**: 系统默认会自动管理线程池的大小,但也可以通过`ThreadPool.GetMaxThreads`和`ThreadPool.SetMaxThreads`来设置最大线程数,以及`ThreadPool.GetMinThreads`和`ThreadPool....

    QT_ThreadPool.rar

    1. **线程池类(ThreadPool)**:这是整个线程池的管理者,它负责创建、管理和调度工作线程。当有新任务提交时,线程池会检查是否有空闲线程,如果有则直接分配,如果没有则等待已有线程完成任务后复用。 2. **工作...

    ThreadPool.rar

    通过对"C++ ThreadPool.rar"的分析,我们可以看出,这个项目提供了一个基础的C++线程池实现,有助于理解如何在实际应用中高效地管理和调度并发任务。这对于大型软件开发,特别是需要大量并发处理的场景,如网络...

    C#判断线程池中所有的线程是否已经完成

    首先,我们来看一下`ThreadPool.RegisterWaitForSingleObject`方法。这个方法用于将一个回调函数注册到一个等待处理的对象上,当该对象变为可通知状态时,回调函数会被调用。在这里,我们使用一个`AutoResetEvent`...

    AN平台中端人证及访客ThreadPool.zip

    标题中的"AN平台中端人证及访客ThreadPool.zip"暗示了这个压缩包包含的是关于AN平台中端人证及访客系统中线程池相关的源代码、设计文档或者实现细节。这个系统可能涉及人脸识别和访客管理,需要高效地处理大量并发...

    用于大型服务器地完成端口+多线程池的结合IOCP+threadpool.zip

    这个名为"用于大型服务器地完成端口多线程池的结合IOCP+threadpool.zip"的压缩包文件包含了实现这一目标的相关源代码,主要由CompletionIoServer.cpp、CompletionIoClient.cpp、CompletionIoServer.h和...

    Java版线程池ThreadPool.zip

    Java线程池(ThreadPool)是Java并发编程中的一个重要概念,它是多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池可以有效控制运行的线程数量,如果线程数量超过了最大数量,...

    threadpool.zip

    综上所述,"threadpool.zip" 包含了一个实现 Nginx 线程池功能的示例代码,涵盖了线程池的创建、任务调度、线程同步和通信等核心概念。通过深入学习和理解这些源码,开发者可以更好地掌握如何在实际项目中应用线程池...

Global site tag (gtag.js) - Google Analytics