首页 > 编程语言 >C# 中定义自己的ThreadPoolQueue

C# 中定义自己的ThreadPoolQueue

时间:2023-11-24 10:44:18浏览次数:31  
标签:定义 C# object ThreadPoolQueue CxThreadPoolQueue Queue actionQueue 2.2 public

目录

一 背景

在实际的开发过程中,我们经常有一种需求就是我们的任务需要放到线程池中进行执行,并且这些任务需要逐一放到 Queue中进行独立的执行,而且要保证其高效,所以今天分享一个用于解决这样的一个场景的CxThreadPoolQueue类用于解决这个问题。

二 源码及分析

2.1 源码展示

using Pangea.Logging;
using System;
using System.Collections.Generic;
using System.Threading;

namespace Pangea.Library
{
  public class CxThreadPoolQueue
  {
    private readonly Queue<CxThreadPoolQueue.ActionItemInfo> actionQueue = new Queue<CxThreadPoolQueue.ActionItemInfo>();
    private bool autoProcess = true;
    private volatile bool hasThread;

    public CxThreadPoolQueue(string name)
    {
      this.Name = name;
    }

    public int Count
    {
      get
      {
        return this.actionQueue.Count;
      }
    }

    public bool AutoProcess
    {
      get
      {
        return this.autoProcess;
      }
      set
      {
        this.autoProcess = value;
      }
    }

    public string Name { get; set; }

    public void Clear()
    {
      lock (this)
        this.actionQueue.Clear();
    }

    public void QueueActionItem(Action<object> action)
    {
      this.QueueActionItem(action, (object) null);
    }

    public void QueueActionItem(Action<object> action, object arg)
    {
      if (action == null)
        return;
      lock (this)
      {
        this.actionQueue.Enqueue(new CxThreadPoolQueue.ActionItemInfo(action, arg));
        if (this.actionQueue.Count != 1 || !this.autoProcess)
          return;
        ThreadPool.QueueUserWorkItem(new WaitCallback(this.ProcessQueuedActionItems));
      }
    }

    public void ProcessQueuedActionItems(object arg)
    {
      bool flag = true;
      while (true)
      {
        CxThreadPoolQueue.ActionItemInfo actionItemInfo;
        lock (this)
        {
          if (flag && this.hasThread)
            break;
          this.hasThread = true;
          if (!flag && this.actionQueue.Count > 0)
            this.actionQueue.Dequeue();
          if (this.actionQueue.Count < 1)
          {
            this.hasThread = false;
            break;
          }
          actionItemInfo = this.actionQueue.Peek();
        }
        try
        {
          if (actionItemInfo.ActionItem != null)
            actionItemInfo.ActionItem(actionItemInfo.Arg);
        }
        catch (Exception ex)
        {
          Log.WriteIfEnabled(LogCategory.Warning, this.Name, string.Format("caught {0} exception. Message: '{1}'", (object) ex.GetType(), (object) ex.Message));
        }
        flag = false;
      }
    }

    private struct ActionItemInfo
    {
      public readonly Action<object> ActionItem;
      public readonly object Arg;

      public ActionItemInfo(Action<object> actionItem, object arg)
      {
        this.ActionItem = actionItem;
        this.Arg = arg;
      }
    }
  }
}

2.2 源码分析

2.2.1 定义ActionItemInfo

注意这里需要了解这里定义成结构体的区别,这个结构体用于传入外部的委托和参数,这个对象也是当前CxThreadPoolQueue中定义的的Queue对象内部保存的任务队列,这个是整个CxThreadPoolQueue中的基础

2.2.2 定义AutoProcess属性

这个属性默认值为True也就是如果当前内部的Queue只要数量大于0,便会自动的执行ProcessQueuedActionItems这个方法用于将当前的任务放到ThreadPool中进行处理,如果外部将AutoProcess设置为False,那么便需要外部主动调用ProcessQueuedActionItems这个方法,当然调用的时候可以放到线程池中也可以不放到线程中执行,这个就是看自己的需要了。(这里建议使用默认的AutoProcess属性)

2.2.3 分析ProcessQueuedActionItems方法

这个是整个执行过程中的重中之重,这里需要注意的是Queue的PeekDequene的区别,前者只会从Queue中拿出第一条数据,但是并不会从Queue中移除这条记录,但是Dequeue是直接从Queue中取出的一条最早的一条记录,这个需要明确。

标签:定义,C#,object,ThreadPoolQueue,CxThreadPoolQueue,Queue,actionQueue,2.2,public
From: https://www.cnblogs.com/seekdream/p/17853208.html

相关文章

  • Docker 常用命令
    镜像(Image)篇1.查看Docker中已有的镜像dockerimagels还有一个dockerimages这是一个旧版的命令,自Docker17.06版本引入dockerimage的命令参数-a列表出有的镜像2.搜索镜像dockersearchubuntu最好下载official为OK的,这表示是官方认可的,这命令中的"ubunt......
  • UEC++头文件添加与函数查找方法
    1.官方函数查找与应用技巧在蓝图中插入函数(中文也可以),右键能看到库名;官网也能查找函数名和使用方法;C++中使用可以将蓝图转化2.UEC++头文件添加VS编译时缺失头文件会报错,ctrl单击调用的函数,进入.h文件中查看的地址,将地址classes后面的目录用#clucde放入如下图如果报错......
  • eclipse查看一个方法被谁引用(调用)的快捷键四种方式
    1.(首推)双击选中该方法,Ctrl+Alt+H如果你想知道一个类的方法到底被那些其他的类调用,那么请选中这个方法名,然后按“Ctrl+Alt+H”,Eclipse就会显示出这个方法被哪些方法调用,最终产生一个调用关系树。2.(次推)选中该方法,Ctrl+Shift+G就显示这个方法被谁引用了,查询在整个工作区中被谁......
  • std::function 与 std::bind解决类成员函数作为回调函数的问题
    1、std::functionstd::function是一个模板类,其可对C++可调用的对象进行封装,比如,成员函数、静态函数等;它的基本作用是简化调用的复杂程度,归一化调用方式。std::function<int(int,int)>int_function:声明方式为<返回值类型(参数类型1,参数类型2,...)>,其可封装任何可调用的......
  • PLC通过lora网关采集温室大棚温湿度数据
    概述:运用lora网关远程控制大棚内风机,日光灯,温湿度传感器等设备。可以实现远程获取现场环境的空气温湿度、土壤水分温度、二氧化碳浓度、光照强度可以自动控制温室湿帘风机、喷淋滴灌、加温补光等设备,并向远程计算机端推送实时数据,实现现场环境信息化,智能化远程管理。减少人工成......
  • 工作常用的EXCEL公式 | vlookup和match函数的应用
    数据源:返回多列结果: ......
  • 基于html5+javascript技术开发的房贷利率计算器,买房的码农们戳进来
    房贷计算器是一款专为购房者设计的实用工具应用,其主要功能是帮助用户详细计算房贷的还款金额、利息以及还款计划等。通过这款软件,用户可以更加便捷地了解到自己的还款情况和计划,从而更好地规划自己的财务。下面将对房贷计算器进行详细的介绍。体验地址房贷计算器体验地址关键代码<t......
  • UEC++中VS标红误报解决办法
    实测可行:1、打开工程2、右键工程->属性3、左侧找到NMake4、然后在打开的右侧界面中找到"包含搜索路径(IncludeSearchPath)",点击并选择编辑5、添加新路径$(SolutionDir)Intermediate\Build\Win64\UE4Editor\Inc\$(SolutionName)6、插件的路径需要修改具体的插件路径7、将......
  • ConfigureAwait in .NET8
    ConfigureAwaitin.NET8ConfigureAwait(true)和ConfigureAwait(false)首先,让我们回顾一下原版ConfigureAwait的语义和历史,它采用了一个名为continueOnCapturedContext的布尔参数。当对任务(Task、Task<T>、ValueTask或ValueTask<T>)执行await操作时,其默认行为是捕获“上......
  • 文心一言 VS 讯飞星火 VS chatgpt (142)-- 算法导论12.1 2题
    二、用go语言,二叉搜索树性质与最小堆性质(见6.1节)之间有什么不同?能使用最小堆性质在O(n)时间内按序输出一棵有n个结点树的关键字吗?可以的话,请说明如何做,否则解释理由。文心一言:在二叉搜索树(BinarySearchTree,BST)和最小堆(MinHeap)中,元素的排列顺序都是根据其关键字的......