C# 的TaskScheduler

        在C#中,TaskScheduler 是一个抽象类,用于控制任务的执行方式,特别是它们如何被安排到线程池中的线程上执行。

TaskScheduler 负责将 Task 对象排队并决定何时、以何种方式执行这些任务。

TaskScheduler 的作用

  • 调度任务:将任务分配给线程池中的线程执行。
  • 控制并发:通过限制同时执行的任务数量来控制并发级别。
  • 异常处理:虽然不是直接由 TaskScheduler 处理异常,但它通过控制任务的执行环境间接影响了异常的处理方式。

如何使用 TaskScheduler

        通常,我们不需要直接创建 TaskScheduler 的实例,因为 Task 类和 TaskFactory 类提供了足够的方法来使用默认的 TaskScheduler(通常是 TaskScheduler.Default,它对应于线程池)。

        然而,在某些情况下,你可能需要自定义 TaskScheduler 来满足特定的需求。

示例:使用默认的 TaskScheduler

        大多数情况下,你不需要显式地使用 TaskScheduler,因为 Task.Run 和 Task.Factory.StartNew(当不提供 TaskScheduler 时)默认使用 TaskScheduler.Default

// 使用 Task.Run 启动一个后台任务  
Task.Run(() =>  
{  // 这里执行耗时操作  Console.WriteLine("任务正在后台执行...");  Thread.Sleep(1000); // 模拟耗时操作  Console.WriteLine("任务完成.");  
});  // 等待任务完成(仅为了示例,实际代码中通常不会这样做)  
Task.Delay(2000).Wait(); // 确保主线程等待足够长的时间以看到后台任务的结果
示例:自定义 TaskScheduler

        如果你需要自定义任务调度逻辑(例如,限制并发任务的数量),你可以继承 TaskScheduler 并实现其抽象方法。然而,这通常是一个高级用法,需要深入理解多线程编程和 Task 的工作机制。

        这里是一个简化的例子,说明如何继承 TaskScheduler,但请注意,这个例子并没有真正实现任务调度逻辑,而只是展示了如何开始自定义:

public class LimitedConcurrencyTaskScheduler : TaskScheduler  
{  // 假设我们有一个限制并发数的字段  private readonly int _maxConcurrencyLevel;  private int _activeTasks;  public LimitedConcurrencyTaskScheduler(int maxConcurrencyLevel)  {  _maxConcurrencyLevel = maxConcurrencyLevel;  }  // 省略了 QueueTask, TryExecuteTaskInline, GetScheduledTasks 等方法的实现  // 这里只是展示如何开始,实际上你需要实现这些方法来控制任务的调度  protected override void QueueTask(Task task)  {  // 这里应该有逻辑来将任务添加到队列中,并根据需要执行它们  // 但由于这是示例,我们只是简单地将任务计数增加  Interlocked.Increment(ref _activeTasks);  // 注意:这实际上并没有真正地将任务排队或执行,只是演示  // 在真实实现中,你应该在这里将任务放入某种队列中,并在有可用线程时执行它们  }  // ... 其他方法的实现  
}  // 注意:上面的 LimitedConcurrencyTaskScheduler 只是一个框架,并没有完整实现  
// 在实际使用中,你需要完整实现所有抽象方法,并根据需要添加额外的逻辑

        由于自定义 TaskScheduler 的实现相对复杂,且容易出错,因此通常建议仅在我们确实需要控制任务执行的细节时才这样做。在大多数情况下,使用默认的 TaskScheduler 或 Task.Run 就足够了。


补充:

        在C#中,如果有大量task同时执行,假设我们需要限制同时执行的Task的最大数量为5,我们可以通过自定义一个TaskScheduler来实现,但这种方法相对复杂且容易出错。更常见和简单的方法是使用SemaphoreSlim来限制并发量

   SemaphoreSlim是一个轻量级的信号量,用于控制对共享资源的并发访问。你可以使用它来限制同时执行的Task数量。

        下面是一个使用SemaphoreSlim来限制Task最大执行个数的例子:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading;  
using System.Threading.Tasks;  class Program  
{  static SemaphoreSlim semaphore = new SemaphoreSlim(5); // 初始化为5,表示同时允许5个任务执行  static async Task Main(string[] args)  {  // 假设我们有10个任务需要执行  var tasks = Enumerable.Range(1, 10).Select(async i =>  {  await semaphore.WaitAsync(); // 等待信号量可用  try  {  // 执行任务  Console.WriteLine($"任务 {i} 开始执行,当前时间:{DateTime.Now:HH:mm:ss.fff}");  await Task.Delay(1000); // 模拟耗时操作  Console.WriteLine($"任务 {i} 执行完成,当前时间:{DateTime.Now:HH:mm:ss.fff}");  }  finally  {  semaphore.Release(); // 释放信号量  }  }).ToList();  // 等待所有任务完成  await Task.WhenAll(tasks);  Console.WriteLine("所有任务执行完成。");  }  
}

         在上面这个例子中,我们创建了一个SemaphoreSlim实例,初始化为5,表示同时最多允许5个任务执行。

        然后,我们创建了10个任务,每个任务在执行前都会调用semaphore.WaitAsync()来等待信号量变得可用。当信号量可用时,任务会继续执行,并在执行完毕后通过semaphore.Release()释放信号量,以便其他任务可以执行。

        这种方法简单且有效,不需要我们深入了解TaskScheduler的内部实现,就可以轻松控制并发量。同时,它也避免了自定义TaskScheduler可能带来的复杂性和潜在的错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/870883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

querylist多线程采集curlMulti时,报错Curl error(60)

前言 在使用querylist多线程采集的时候,报错: Curl error(60)。测试了下用http时没有问题,https时有问题。其原因在于多线程采集库引用的另一个库有问题。需要手动更改。 解决 找到:vendor/ares333/php-curl/src/Curl.php 文件&#xff0c…

网络 闲聊

闲谈 闲话 网络安全——>网络空间安全 网络空间:一个由信息基础设备组成互相依赖的网络 继:海、陆、空、天、的第五大空间 信息安全的一个发展: 通信保密阶段---计算机安全---信息系统安全---网络空间安全 棱镜门事件 棱镜计划&…

Visual Studio Code:深度解析与开发者的新宠

在计算机行业中,开发工具的选择至关重要,它直接影响到开发者的效率和项目的质量。近年来,Visual Studio Code(简称VSCode)凭借其强大的功能和灵活的定制性,在众多编辑器中脱颖而出,成为了开发者…

linux系统php开机自启动 phpfpm

1、关闭当前的php环境,运行命令,下面二选一,根据你自己情况来选 service php-fpm stop 或 systemctl stop php-fpm 2、运行命令vim /etc/systemd/system/phpfpm.service,输入以下代码,注意php-fpm路径需要改成自己的路径 [Unit]…

Redis原子计数器incr,防止并发请求

一、前言 在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试。这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流量冲击…

Twitter API 使用教程:入门到实践

Twitter API为开发者提供了丰富的接口,用于访问Twitter上的公开数据和实现特定功能。从获取推文到用户认证,Twitter API在数据挖掘、社交分析和应用开发中扮演着重要角色。 关键词 Twitter API, 开发者指南,社交媒体,数据访问 …

elementary os 8 2024年07月新动态

具体信息请登录官网查询 **OS 7更新** Photos 8已经作为Flatpak应用发布到AppCenter。这意味着你可以通过从AppCenter安装Flatpak版本来继续接收Photos的更新,即使在旧版本的elementary OS上,而且Photos现在也很容易为那些运行除elementary OS之外的Lin…

Java中的Set系列集合超详解

Set List是有序集合的根接口,Set是无序集合的根接口,无序也就意味着元素不重复。更严格地说,Set集合不包含一对元素e1和e2 ,使得e1.equals(e2) ,并且最多一个空元素。   使用Set存储的特点与List相反:元素…

腾讯云如何设置二级域名?

什么是二级域名? 例如我已申请的域名为: test.com //顶级域名 现在我开发的应用要部署到二级域名: blog.test.com 1、打开腾讯云控制台的我的域名,然后点击解析 2、在我的解析页面点击添加记录,然后需注意红色方框处…

生物素标记的柚皮苷探针;Biotin-Naringin

生物素标记的柚皮苷探针(Biotin-Naringin)是一种结合了生物素(Biotin)和柚皮苷(Naringin)特性的化合物,它在有机合成及药物化学技术领域具有重要意义。以下是对该探针的详细解析: 一…

秋招Java后端开发冲刺——Mybatis

一、基本知识 1. 介绍 MyBatis 是 Apache 的一个开源项目,它封装了 JDBC,使开发者只需要关注 SQL 语句本身,而不需要再进行繁琐的 JDBC 编码。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java POJO(Plain …

设计模式Base

设计模式是在软件开发过程中总结出来的一些经验,它们大多数都遵循一些基本原则: 单一职责原则(SRP):一个类应该只有一个引起它变化的原因。也就是说,一个类应该只有一个职责。开放封闭原则(OCP…

Everything搜索无法搜索到桌面的文件(无法检索C盘 或 特定路径的文件)

现象描述 在Everything搜索框中输入桌面已存在的文件或随便已知位置的文件,无法找到。 搜索时检索结果中明显缺少部分磁盘位置的,例如无法检索C盘,任意关键字搜索时结果中没有位于C盘的,无论怎样都搜不到C盘文件。 解决方法 在…

CentOS搭建FTP服务器教程

CentOS搭建FTP服务器教程 在互联网时代,文件传输是日常工作中不可或缺的一部分。FTP(文件传输协议)作为一种标准的网络协议,被广泛用于在互联网上传输文件。本文将详细介绍如何在CentOS系统上搭建FTP服务器,以便您能轻…

L1 Simple_ReAct_Agent

参考自https://www.deeplearning.ai/short-courses/ai-agents-in-langgraph,以下为代码的实现。 Basic ReAct Agent(manual action) import openai import re import httpx import os from dotenv import load_dotenv, find_dotenvOPENAI_API_KEY os.getenv(OPEN…

pip install .自己构建工程文件报错error: subprocess-exited-with-error解决办法

有时我们直接使用pip install xxx安装某个三方文件时候会发现安装不了,会报各种问题。 这时候我们只能通过下载源码自己手动编译。 等我们下好源码开始编译的时候又会出现很多问题。 下面就举一个栗子作为解决问题的思路: 比如我我想要安装diff-gaussian-rasterization,直…

python 66 个冷知识 0712

66个有趣的Python冷知识 字典合并 从Python 3.9开始,可以使用 | 操作符合并字典。 多继承 Python支持多继承,类可以继承多个父类。 ABC模块 abc 模块提供了定义抽象基类的工具。 泛型 typing 模块提供了泛型支持。 类型别名 使用 typing 模块可以创建…

DP讨论——设计模式怎么来的?

眼中没有设计模式,代码里就找不到设计模式 几年前还在搞c开发,觉得设计模式离我太遥远,而且觉得设计模式太复杂太高大上,比较恐惧。 后来接触了oopc(接触了rtthread整个都是oopc实现的rtos),再…

LTE系统OFDM符号持续时间计算

LTE系统OFDM符号持续时间计算 给定等式:7个OFDM符号的持续时间 0.5ms(1个slot) - 160Ts - 6144*Ts 其中: 1个slot 0.5msTs是LTE系统的基本时间单位 步骤分解 理解时间资源结构: 1个无线帧 10ms1个子帧 1ms 2个slot1个slot 0.5ms1个…

Spring Boot Vue 毕设系统讲解 9 【Spark】

SuppressWarnings("serial") Configuration ConfigurationProperties(prefix"spark") public class SparkConfig implements Serializable {//spark的安装地址private String sparkHome ".";//应用的名称private String appName "mySpar…