博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基元线程同步构造之 在一个内核构造可用时调用一个方法
阅读量:5928 次
发布时间:2019-06-19

本文共 5898 字,大约阅读时间需要 19 分钟。

  让一个线程不确定的等待一个内核对象进入可用状态,这对线程的内存资源来说是一种浪费。因此,线程池提供了一种方式,在一个内核对象变得可用的时候调用一个方法。这是通过System.Threading.ThreadPool类的静态RegisterWaitForSingleObject方法来实现的。该方法有几个重载的版本,但这些版本全都是很相似。以下是一个较常用的重载版本的原型:

  

public static RegisteredWaitHandle RegisterWaitForSingleObject(   WaitHandle waitObject,   WaitOrTimerCallback callback,   Object state,   Int32 millsecondsTimeoutInterval,   Boolean executeOnlyOnce);

参数说明:

  waitObject:标识了你希望线程池等待的内核对象,由于这个参数的类型是抽象基类WaitHandle,所以可以指定从这个基类派生的任何类。具体的说,可以传递          对一个Semaphore、Mutex、AutoResetEvent或者ManualResetEvent对象的引用。

  callback:标识了希望线程池线程调用的方法,这个回调方法必须匹配System.Threading.WaitOrTimerCallback委托:

          public delegate void WaitOrTimerCallback(Object state,Boolean timedOut)

  state:允许指定一些状态数据,线程池线程调用回调方法时,会将这个状态传给回调方法;如果没有特殊的状态数据需要传递,就传递null.

  millsecondsTimeoutInterval:指定了线程池在等待内核对象收到信号时的超时时间。一般传递 Timeout.Infinite(-1),将超时时间设为“无限长”。通俗点就是每                间隔多少时间执行一次 callback方法。

  executeOnlyOnce:为true时,线程池线程只执行回调方法一次,为false时,那么内核对象每次收到信号,线程此线程都会执行回调方法。

调用回调方法是,会向它传递状态数据和一个名为timedOut的Boolean值(通俗的说也就是在规定的时间millsecondsTimeoutInterval内,内核对象是否收到了信号),如果timedOut为false,方法知道他之所以被调用,是因为内核对象收到了信号。

     如果timedOut为true,方法知道它之所以被调用,是因为内核对象在指定的时间内没收到信号。

   注意:RegisterWaitForSingleObject方法返回的是对一个RegisteredWaitHandle对象的引用。这个对象标识了线程池线程正在它上面等待的内核对象。如果处于任何原因,你的应用程序向告诉线程池停止监视已登记的等待句柄,应用程序可以调用RegisteredWaitHandle的Unregister方法: 

public Boolean Unregister(WaitHandle waitObject);

  参数说明: waitObject参数指出,针对已登记等待句柄的、队列中的所有工作项都执行好之后,你想如何收到通知。

    如果不想接收通知,应该为这个参数传递null.

    如果传递的是对一个WaitHandle派生对象的有效引用,那么针对已登记的等待句柄的所有待决的工作项都执行完毕后,线程池线程就会向对象发出信号。

  以下代码演示了如果在一个AutoResetEvent对象收到信号之后,让一个线程池线程调用一个方法:

  

1 // This example shows how a Mutex is used to synchronize access 2 // to a protected resource. Unlike Monitor, Mutex can be used with 3 // WaitHandle.WaitAll and WaitAny, and can be passed across 4 // AppDomain boundaries. 5  6 using System; 7 using System.Threading; 8  9 internal static class RegisteredWaitHandleDemo10 {11     public static void Main()12     {13         // Construct an AutoResetEvent (initially false)14         AutoResetEvent are = new AutoResetEvent(false);15 16         // Tell the thread pool to wait on the AutoResetEvent告诉线程池在AutoResetEvent上等待17         RegisteredWaitHandle rwh = ThreadPool.RegisterWaitForSingleObject(18            are,             // Wait on this AutoResetEvent 在这个AutoResetEvent上等待19            EventOperation,  // When available, call the EventOperation method 如果可用,就调用EventOperation方法20            null,            // Pass null to EventOperation 向EventOperation传递null21            5000,            // Wait 5 seconds for the event to become true 等5秒事件变成true,就执行 EventOperation回调方法,                    // 也就是每间隔5秒执行一次EventOperation22            false);          // Call EventOperation everytime the event is true 每次事件为true时,都调用 EventOperation23 24         // Start our loop25         Char operation = (Char)0;26         while (operation != 'Q')27         {28             Console.WriteLine("S=Signal, Q=Quit?");29             operation = Char.ToUpper(Console.ReadKey(true).KeyChar);30             if (operation == 'S') are.Set(); // User want to set the event31         }32 33         // Tell the thread pool to stop waiting on the event,此处传递的是NULL,就不会向任何对象发送信号34         rwh.Unregister(null);35     }36 37     // This method is called whenever the event is true or38     // when 5 seconds have elapsed since the last callback/timeout39     private static void EventOperation(Object state, Boolean timedOut)40     {41         Console.WriteLine(timedOut ? "Timeout" : "Event became true");42     }43 }

以下的示例代码中 增加了取消登记时候发送信号的功能:

  

1 // This example shows how a Mutex is used to synchronize access 2 // to a protected resource. Unlike Monitor, Mutex can be used with 3 // WaitHandle.WaitAll and WaitAny, and can be passed across 4 // AppDomain boundaries. 5  6 using System; 7 using System.Threading; 8  9 internal static class RegisteredWaitHandleDemo10 {11     public static void Main()12     {13         // Construct an AutoResetEvent (initially false)14         AutoResetEvent are = new AutoResetEvent(false);15 16         AutoResetEvent arereult = new AutoResetEvent(false);17 18         System.Threading.Thread thr = new Thread(new ParameterizedThreadStart(TestUnregistered));19         thr.Start(arereult);20 21         // Tell the thread pool to wait on the AutoResetEvent22         RegisteredWaitHandle rwh = ThreadPool.RegisterWaitForSingleObject(23            are,             // Wait on this AutoResetEvent24            EventOperation,  // When available, call the EventOperation method25            null,            // Pass null to EventOperation26            5000,            // Wait 5 seconds for the event to become true27            false);          // Call EventOperation everytime the event is true28 29         // Start our loop30         Char operation = (Char)0;31         while (operation != 'Q')32         {33             Console.WriteLine("S=Signal, Q=Quit?");34             operation = Char.ToUpper(Console.ReadKey(true).KeyChar);35             if (operation == 'S') are.Set(); // User want to set the event36         }37 38         // Tell the thread pool to stop waiting on the event 取消注册后,向arereult发送信号,TestUnregistered就会解除阻塞39         rwh.Unregister(arereult);40 41         Console.ReadLine();42     }43 44     // This method is called whenever the event is true or45     // when 5 seconds have elapsed since the last callback/timeout46     private static void EventOperation(Object state, Boolean timedOut)47     {48         Console.WriteLine(timedOut ? "Timeout" : "Event became true");49     }50 51     private static void TestUnregistered(object waithandle)52     {53         ((AutoResetEvent)waithandle).WaitOne();54 55         Console.WriteLine(" Test is TestUnregistered ");56     }57 58 }

 

  

 以上的理解来源于 CLR 书中的理解。。。。。欢迎各位大侠们拍砖指正错误之处。。。。。。。。。。

转载于:https://www.cnblogs.com/huaan011/p/3580406.html

你可能感兴趣的文章
走进webpack(2)--第三方框架(类库)的引入及抽离
查看>>
[译] 所有你需要知道的关于完全理解 Node.js 事件循环及其度量
查看>>
脚本监控网络状态,输出日志并归档(V2)
查看>>
IOS常用加密Encryption
查看>>
(六十九)复合语句
查看>>
每天一个linux命令(4):mkdir命令
查看>>
利用LoadRunner编写socket性能测试脚本
查看>>
Win2008学习(十九),AD RMS权限策略模板
查看>>
SCVMM2008R2学习(九),虚拟机的迁移
查看>>
shell下action:command not found
查看>>
mysql 主从错误 skip方法
查看>>
Java 泛型的使用限制
查看>>
DNS主配置文件的几个选项
查看>>
Liunx的安装详解
查看>>
[AAuto]批量添加按钮及注册命令演示
查看>>
c++中指针的理解demo
查看>>
代理键--surrogate keys
查看>>
Linux一条刚接触的命令该如何去学习它?
查看>>
在系统中复用HTTP Status来映射系统的状态
查看>>
Spring+SpringMVC+Mybatis整合,你可能遇到的问题
查看>>