当前位置: 首页 > news >正文

C#多线程Thread、Task

在C#中,线程可以用于完成需要耗费较长时间的操作,而不会阻塞用户界面。一个程序可以有多个线程,每个线程可以并行执行代码。

在C#中,可以使用System.Threading.Thread类来创建和控制线程,使用System.Threading.Mutex类来同步线程。

多线程基本例子

下面是一个C#多线程的简单示例:

using System;
using System.Threading;class Program
{static void Main(string[] args){Thread thread1 = new Thread(new ThreadStart(Work1));Thread thread2 = new Thread(new ThreadStart(Work2));thread1.Start();thread2.Start();thread1.Join();thread2.Join();}static void Work1(){for(int i = 0; i < 5; i++){Console.WriteLine("Work 1 is progressing");Thread.Sleep(1000);}}static void Work2(){for(int i = 0; i < 5; i++){Console.WriteLine("Work 2 is progressing");Thread.Sleep(1000);}}
}

在上面的代码中,我们创建了两个线程,分别执行Work1和Work2方法。我们使用Thread.Start方法启动线程,使用Thread.Join方法等待线程完成。

每个线程会打印出一条消息,然后休眠一秒钟,这个过程会重复五次。因为这两个线程是并行执行的,所以"Work 1 is progressing"和"Work 2 is progressing"消息会交替出现。

需要注意的是,多线程编程是一个复杂的主题,上面只是一个简单的例子。在实际的编程中,你需要处理更复杂的问题,比如线程同步、线程优先级、异常处理等等。

线程同步

在C#中, lock关键字可用于确保一次只有一个线程在执行某个代码块, 这可用于防止多线程同时修改共享的数据结构:

class Program
{static int counter = 0;static object lockObj = new object();static void Main(string[] args){Thread thread1 = new Thread(IncrementCounter);Thread thread2 = new Thread(IncrementCounter);thread1.Start();thread2.Start();thread1.Join();thread2.Join();Console.WriteLine($"Counter is {counter}");}static void IncrementCounter(){for (int i = 0; i < 100000; i++){lock (lockObj){counter++;}}}
}

在这个例子中,lock关键字确保了一次只有一个线程在增加计数器的值。如果没有lock关键字,两个线程可能会同时读取和修改counter变量,从而导致数据的不一致。

线程优先级

在C#中,可以通过Thread.Priority属性来设置线程的优先级。

Thread thread = new Thread(() => 
{// Do Something
});thread.Priority = ThreadPriority.Highest;  // 设置线程的优先级为最高thread.Start();

请注意,线程优先级应该谨慎使用,因为它可能会导致线程饿死,也就是高优先级的线程持续运行,而低优先级的线程永远得不到运行的机会。

异常处理

在线程中运行的代码可能会抛出异常,需要正确地处理这些异常。下面是一个处理线程异常的例子:

Thread thread = new Thread(() =>
{try{// Do Something}catch (Exception ex){Console.WriteLine($"Caught exception: {ex.Message}");}
});thread.Start();

在这个例子中,我们在线程的代码块中使用try/catch语句来捕获和处理异常。

Task

在C#中,ThreadTask都可以用来实现多线程编程,但它们之间存在一些重要的区别。

Thread:

  • Thread是一个较低级别的方式来处理多线程,需要手动创建和管理线程。
  • Thread提供了对操作系统线程的直接控制,这意味着你可以设置线程的优先级、线程的状态等。
  • Thread不支持返回值和取消操作。
  • Thread需要手动处理异常。

Task:

  • Task是一个更高级别,更抽象的概念,它使用线程池来管理线程,无需用户手动创建和管理线程。
  • Task可以返回结果,并且支持取消操作。
  • Task可以自动处理异常,并且可以在多个Task之间传播异常。
  • Task可以更容易地实现异步操作。

下面是两个例子,分别展示了如何使用ThreadTask

Thread 例子:

class Program
{static void Main(string[] args){Thread thread = new Thread(() => {Console.WriteLine("Hello from thread");});thread.Start();thread.Join();}
}

Task 例子:

class Program
{static void Main(string[] args){Task task = Task.Run(() => {Console.WriteLine("Hello from task");});task.Wait();}
}

在实际编程中,如果可能的话,推荐使用Task,因为它提供了更多的功能,而且更容易使用。

Task其它用法

Task有很多高级用法,例如你可以使用Task来实现异步编程,还可以使用ContinueWith方法来链接多个任务。以下是一些例子:

使用Task实现异步编程

在C#中,asyncawait关键字可以与Task一起使用,以实现异步编程。这可以避免阻塞主线程,提高程序的响应性。

static async Task Main(string[] args)
{Task<int> task = CalculateSumAsync(10, 20);// Do other things while CalculateSumAsync is running in the backgroundint result = await task;Console.WriteLine($"The result is {result}");
}static async Task<int> CalculateSumAsync(int a, int b)
{// Simulate a long-running operationawait Task.Delay(1000);return a + b;
}

使用ContinueWith链接多个任务

ContinueWith方法可以用来链接多个任务,当一个任务完成后,另一个任务会自动开始。

Task<int> task1 = Task.Run(() => 
{// Do some workreturn 1;
});Task<int> task2 = task1.ContinueWith(t => 
{// This task starts after task1 completesreturn t.Result + 1;
});task2.Wait();
Console.WriteLine($"The result is {task2.Result}");  // Output: The result is 2

使用Task.WhenAll等待多个任务完成

Task.WhenAll方法可以用来等待多个任务都完成。

Task task1 = Task.Run(() => 
{// Do some work
});Task task2 = Task.Run(() => 
{// Do some work
});await Task.WhenAll(task1, task2);
Console.WriteLine("All tasks completed");

以上就是Task的一些高级用法,Task提供了很多功能,使得多线程编程变得更加简单和高效。

相关文章:

C#多线程Thread、Task

在C#中&#xff0c;线程可以用于完成需要耗费较长时间的操作&#xff0c;而不会阻塞用户界面。一个程序可以有多个线程&#xff0c;每个线程可以并行执行代码。 在C#中&#xff0c;可以使用System.Threading.Thread类来创建和控制线程&#xff0c;使用System.Threading.Mutex类…...

Qt QWebSocket实现JS调用C++

目录 前言1、QWebChannel如何与网页通信2、QWebSocketQWebChannel与网页通信2.1 WebSocketTransport2.2 WebSocketClientWrapper2.3 初始化WebSocket服务器2.4 前端网页代码修改 总结 前言 本篇主要介绍实现JS调用C的另一种方式&#xff0c;即QWebSocketQWebChannel。与之前的…...

Android Matrix的使用详解(通过矩阵获取到图片缩放比例和角度)

网上查了好久相关的资料&#xff0c;都没有明确的答案。最终通过多次测试结果&#xff0c;结合安卓定义的矩阵含义&#xff0c;推算出来矩阵的数学含义以及相关的计算公式 1.获取Matrix矩阵&#xff1a; Matrix matrix new Matrix(); float[] matrixValues new float[9]; …...

【Spring】bean的生命周期

这里写目录标题 1. 在类中提供生命周期控制方法&#xff0c;并在配置文件中配置init-method&destroy-method&#xff08;配置&#xff09;关闭容器操作1&#xff1a;ctx.close()关闭容器操作2&#xff1a;关闭钩子&#xff1a;ctx.registerShutdownHook() 2. 实现接口来做和…...

C#运算符重载

运算符重载允许你重新定义内置运算符&#xff08;如、-、*等&#xff09;的行为&#xff0c;以便它们可以用于自定义类型&#xff08;类/结构体&#xff09;。通过运算符重载&#xff0c;你可以为自定义类型创建更直观和灵活的操作。 在C#中&#xff0c;可以重载的运算符如下&…...

【L2GD】: 无环局部梯度下降

文章链接&#xff1a;Federated Learning of a Mixture of Global and Local Models 发表期刊&#xff08;会议&#xff09;: ICLR 2021 Conference&#xff08;机器学习顶会&#xff09; 往期博客&#xff1a;FLMix: 联邦学习新范式——局部和全局的结合 目录 1.背景介绍2. …...

2023-11-14 LeetCode每日一题(阈值距离内邻居最少的城市)

2023-11-14每日一题 一、题目编号 1334. 阈值距离内邻居最少的城市二、题目链接 点击跳转到题目位置 三、题目描述 有 n 个城市&#xff0c;按从 0 到 n-1 编号。给你一个边数组 edges&#xff0c;其中 edges[i] [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的…...

AdServices归因和iAd归因集成

AdServices framework 是 Apple 专门为 ASA 提供的归因框架 。尤其在ATT 政策推出以后&#xff0c;app 获取用户 IDFA 的比例大幅降低&#xff0c;传统的依靠IDFA 的方法也无法准确归因。 但是 Apple 为 ASA 开了一个后门&#xff0c;其他广告渠道无法获取用户的 IDFA 作为身份…...

关于 内部类 你了解多少?(详解!!)

目录 1. 什么是内部类&#xff1f; 2. 内部类的分类 3. 内部类 3.1 实例内部类 3.2 静态内部类 4. 局部内部类 5. 匿名内部类 6.对象的打印 “不积跬步无以至千里&#xff0c;不积小流无以成江海。”每天坚持学习&#xff0c;哪怕是一点点&#xff01;&#xff01;&a…...

CNVD-2021-09650:锐捷NBR路由器(guestIsUp.php)RCE漏洞复现 [附POC]

文章目录 锐捷NBR路由器guestIsUp.php远程命令执行漏洞(CNVD-2021-09650)复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 锐捷NBR路由器guestIsUp.php远程命令执行漏洞(CNVD-2021-09650)复现 [附POC] 0x01 前言 免…...

如何在Docker部署Draw.io绘图工具并远程访问

文章目录 前言1. 使用Docker本地部署Drawio2. 安装cpolar内网穿透工具3. 配置Draw.io公网访问地址4. 公网远程访问Draw.io 前言 提到流程图&#xff0c;大家第一时间可能会想到Visio&#xff0c;不可否认&#xff0c;VIsio确实是功能强大&#xff0c;但是软件为收费&#xff0…...

Android APK打包的过程主要步骤

Android APK打包的过程可以概括为以下几个主要步骤&#xff1a; 编译源代码&#xff1a;将开发好的Java源代码编译成Dalvik字节码文件&#xff08;.dex文件&#xff09;&#xff0c;Android安卓该文件包含了Android平台上的运行程序的指令集。打包资源文件&#xff1a;将应用程…...

吃透 Spring 系列—MVC部分

目录 ◆ SpringMVC简介 - SpringMVC概述 - SpringMVC快速入门 - Controller中访问容器中的Bean - SpringMVC关键组件浅析 ◆ SpringMVC的请求处理 - 请求映射路径的配置 - 请求数据的接收 - Javaweb常用对象获取 - 请求静态资源 - 注解驱动 标签 ◆ SpringMV…...

Java面试题(每天10题)-------连载(32)

目录 设计模式篇 1、工厂方法模式&#xff08;利用创建同一接口的不同实例&#xff09;&#xff1a; 2、抽象工厂模式&#xff08;多个工厂&#xff09; 3、单例模式&#xff08;保证对象只有一个实例&#xff09; 4、原型模式&#xff08;对一个原型进行复制、克隆产生类…...

HDP集群Kafka开启SASLPLAINTEXT安全认证

hdp页面修改kafka配置 java代码连接kafka增加对应的认证信息 props.put("security.protocol","SASL_PLAINTEXT");props.put("sasl.mechanism","PLAIN");props.put("sasl.jaas.config","org.apache.kafka.common.securi…...

判断上颌下颌的stl模型坐标轴是否正常

文章目录 研究方向:如何判断?又如何纠正?如何判断?Demo实现:先判断一个遍历相关文件夹下的所有病例如何纠正?Demo相关知识点研究方向:如何判断?又如何纠正? 如何判断? 当然,我们不能以坐标的正负来判断 我们看到这个Bounding Box里面有stl模型的xyz三轴方向的最大值与最…...

C/C++---------------LeetCode第1189. “气球” 的最大数量

气球的最大数量 题目及要求统计法在main内使用 题目及要求 给你一个字符串 text&#xff0c;你需要使用 text 中的字母来拼凑尽可能多的单词 “balloon”&#xff08;气球&#xff09;。 字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 “ba…...

Arthas(阿尔萨斯)--(三)

目录 一、Arthas学习 1、class/classloader相关命令一 1、sc 2、sm 2、class/classloader相关命令二 1、jad 2、mc 3、redefine 三、class/classloader相关命令三 一、Arthas学习 Arthas(阿尔萨斯)--(一) Arthas(阿尔萨斯)--(二) 1、class/classloader相关命令一 …...

《变形监测与数据处理》笔记/期末复习资料(择期补充更新)

变形&#xff1a; 变形是物体在外来因素作用下产生的形状、大小及位置的变化&#xff08;随时间域和空间域的变化&#xff09;&#xff0c;它是自然界普遍存在的现象。 变形体&#xff1a; 一般包括工程建筑物、构筑物、大型机械设备以及其他自然和人工对象等。 变形体和变形…...

Linux:进程替换和知识整合

文章目录 进程程序替换替换原理进程替换的理解 环境变量与进程替换命令行解释器实现逻辑 进程程序替换 前面已经学习了子进程的创建&#xff0c;但是子进程的创建不管怎么说&#xff0c;都是父进程代码的一部分&#xff0c;那么实际上如果想要子进程执行新的程序呢&#xff1f…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...