zoukankan      html  css  js  c++  java
  • 线程池-使用等待事件处理器及超时

    本节将描述如何在线程池中对操作实现超时,以及如何在线程池中正确的等待。

    代码Demo:

    using System;
    using System.Threading;

    在Main方法下面加入以下代码片段:

    static void RunOperations(TimeSpan workerOperationTimeout)
    {
    using (var evt = new ManualResetEvent(false))
    using (var cts = new CancellationTokenSource())
    {
    Console.WriteLine("Registering timeout operations...");
    var worker = ThreadPool.RegisterWaitForSingleObject(
    evt, (state, isTimedOut) => WorkerOperationWait(cts, isTimedOut), null, workerOperationTimeout, true);
    Console.WriteLine("Starting long running operation...");
    ThreadPool.QueueUserWorkItem(_ => WorkerOperation(cts.Token, evt));
    Thread.Sleep(workerOperationTimeout.Add(TimeSpan.FromSeconds(2)));
    worker.Unregister(evt);
    }
    }
    static void WorkerOperation(CancellationToken token, ManualResetEvent evt)
    {
    for (int i = 0; i < 6; i++)
    {
    if (token.IsCancellationRequested)
    {
    return;
    }
    Thread.Sleep(TimeSpan.FromSeconds(1));
    }
    evt.Set();
    }
    static void WorkerOperationWait(CancellationTokenSource cts, bool isTimedOut)
    {
    if (isTimedOut)
    {
    cts.Cancel();
    Console.WriteLine("Worker operation timed out and was canceled.");
    }
    else
    {
    Console.WriteLine("Worker operation succeded.");
    }
    }

    在Main方法中加入以下代码片段:

    RunOperations(TimeSpan.FromSeconds(3));
    RunOperations(TimeSpan.FromSeconds(7));

    工作原理:

    线程池还有一个有用的方法:ThreadPool.RegisterWaitForSingleObject。该方法允许我们将回调函数放入线程池中的队列中。当提供的等待事件处理器收到信号或发生超时时,该回调函数将被调用。这允许我们为线程池中的操作实现超时功能。

    首先按顺序向线程池中放入一个耗时长的操作。他运行6秒钟然后一旦成功完成,会设置一个ManualResetEvent信号类。其它的情况下,比如需要取消操作,则该操作会被丢弃。

    然后我们注册了第二个异步操作。当从ManualResetEvent对象接受一个信号后,该异步操作会被调用。如果第一个操作顺利完成,会设置该信号量。另一种情况是第一个操作还未完成就已经超时。如果发生了该情况,我们会使用CancellationToken来取消第一个操作。

    最后,为操作提供5秒钟的超时时间是不够的。这是因为操作会浪费6秒来完成,只能取消该操作。所以如果提供7秒的超时时间是可行的,该操作会顺利完成。

    注意:当有大量的线程必须处于阻塞状态中等待一些多线程事件发信号时,以上方式非常有用。借助于线程池的基础设施,我们无需阻塞所有这样的线程。可以释放这些线程直到信号事件被设置。在服务器端应用程序中这是个非常重要的应用场景,因为服务器端应用程序要求高伸缩性及高性能。

  • 相关阅读:
    【转】Windows7 下安装 JDK 7 时版本冲突问题解决
    【转】Android开发之旅:环境搭建及HelloWorld
    android开发板
    win7重装系统的配置步骤
    caffe 源码阅读
    caffe 源码阅读
    Python 图像处理: 生成二维高斯分布蒙版
    学习 protobuf(一)—— ubuntu 下 protobuf 2.6.1 的安装
    学习 protobuf(一)—— ubuntu 下 protobuf 2.6.1 的安装
    CMake 添加头文件目录,链接动态、静态库(添加子文件夹)
  • 原文地址:https://www.cnblogs.com/v-haoz/p/9273457.html
Copyright © 2011-2022 走看看