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提供了很多功能,使得多线程编程变得更加简单和高效。

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

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

相关文章

javascript二维数组(22)JavaScript 中的数据类型有哪些?如何进行类型转换?

在 JavaScript 中&#xff0c;数据类型主要分为两种&#xff1a;基本类型和对象类型。 基本类型是指原始数据类型&#xff0c;包括&#xff1a; Number&#xff1a;数值型。可以是整数或浮点数。String&#xff1a;字符串型。用于表示文本数据。Boolean&#xff1a;布尔型。包…

ZYNQ7000---FLASH读写

提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Flash是什么&#xff1f;二、Flash的分类1、内部结构&#xff08;接口&#xff09;区分&#xff1a;2、外部接口区分&#xff1a;SPIQPSI Flash: QSPI 控制…

k8s pod 处于Terminating的原因分析和解决处理——筑梦之路

之前整理了一下各种资源长时间无法回收&#xff0c;解决处理的命令行 k8s 各种资源Terminationg状态处理 —— 筑梦之路_k8s自定义资源修改状态-CSDN博客 这里具体整理下pod长时间处于Terminating状态的相关知识&#xff0c;主要是对前面的补充和完善&#xff0c;作为笔记记录…

京东数据挖掘(京东数据采集):2023年Q3电脑行业数据分析报告

近年来&#xff0c;在远程办公、远程教育等需求的刺激下&#xff0c;电脑的销售增长较为显著。不过&#xff0c;随着市场的成熟乃至饱和&#xff0c;电脑销售市场也逐渐出现增长困难、需求疲软等问题。 2023年第三季度&#xff0c;电脑市场的出货量同比下滑。根据鲸参谋电商数据…

德迅云安全为您介绍关于抗D盾的一些事

抗D盾概述&#xff1a; 抗D盾是新一代的智能分布式云接入系统&#xff0c;接入节点采用多机房集群部署模式&#xff0c;隐藏真实服务器IP&#xff0c;类似于网站CDN的节点接入&#xff0c;但是“抗D盾”是比CDN应用范围更广的接入方式&#xff0c;适合任何TCP 端类应用包括&am…

GB28181 编码规则说明

背景&#xff1a; GB/T28181-2011 《安全防范视频监控联网系统信息传输、交换、控制技术要求》中规定了联网系统应对前端设备、监控中心设备、用户终端ID进行统一编码,该编码具有全局唯一性。这就是国标编码。编码分20位和18位&#xff0c;其中18位编码已经淘汰。下文中&#…

React hooks(一):useState

1.React hooks React hooks是React16.8的新特性&#xff0c;可以让React函数组件具有状态&#xff0c;并提供类似componentDidMount和componentDidUpdate等生命周期方法。 React 早期版本&#xff0c;类组件可以在shouldComponentUpdate中&#xff0c;通过判断props和state是…

搭建yum源并定时同步

一 、安装yum源 1-准备yum目录 cd /data/www/html createrepo -v ./目录 2-安装服务 yum -y install httpd 3-配置服务 /etc/httpd/conf/httpd.conf 4.配置/etc/yum.repo.d/local.rpeo 二、定时更新yum源 #1. 同步整个源到指定目录 [rootV10SP1-1 pac]# reposync -p /root/…

到底什么是Linux?快进来学习!

相信大家对Linux并不陌生吧&#xff1f;Linux 是一种计算机系统&#xff0c;属于基础中的基础&#xff0c;就和我们熟知的Windows一样&#xff0c;都是系统。它是现今最流行和最实用的计算机操作系统&#xff0c;它区别于后台、算法、大数据、前端、测试方向&#xff0c;需要程…

python 随机数生成

生成随机整数 使用 randint() 函数可以生成指定范围内的随机整数。 import random # 生成1到10之间的随机整数 random_int random.randint(1, 10) print(random_int) 生成随机浮点数 random() 方法用于生成 0 到 1 之间的随机浮点数。 import random # 生成0到1之间…

LVGL 日历组件

LVGL 日历组件 calendar 添加到默认组中 lvgl的 calendar 组件会默认添加到旋钮按键组中&#xff0c;需要手动将其删除&#xff0c;否则会聚焦到不可见的控件上。 lv_obj_set_style_pad_all(calendar, 8, LV_STATE_DEFAULT); lv_group_remove_obj(calendar);修改时间范围 年…

[msg_msg] corCTF2021 -- fire_of_salvation

前言 msg_msg 是 kernel pwn 中经常用作堆喷的结构体. 其包含一个 0x30 大小的 header. 但 msg_msg 的威力远不如此, 利用 msg_msg 配合其他堆漏洞可以实现任意地址读写的功能. 程序分析 本题给了源码, 可以直接对着源码看. 并且题目给了编译配置文件, 所以可以直接编译一个…

C++ const与符号表

fun_cpp.cpp //const修饰的全局变量 默认是内部链接&#xff08;只在当前源文件有效 不能直接用于其他源文件&#xff09; const int num_pp 100;//如果必须用在其他源文件 使用只读的全局变量 必须加extern将num转换成外部链接 //extern const int num_pp 100;main_cpp.cpp…

Linux/麒麟系统上部署Vue+SpringBoot前后端分离项目

目录 1. 前端准备工作 1.1 在项目根目录创建两份环境配置文件 1.2 环境配置 2. 后端准备工作 2.1 在项目resources目录创建两份环境配置文件 2.2 环境配置 3. 前后端打包 3.1 前端打包 3.2 后端打包 4、服务器前后端配置及部署 4.1 下载、安装、启动Nginx 4.2 前端项目部署…

Elasticsearch搜索分析引擎本地部署与远程访问

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜索和分析引擎&#xff0c;它提供了一个分布式、多…

【小白的Spring源码手册】 BeanFactoryPostProcessor的注册和用法(BFPP)

目录 前言应用1. 手动注册2. 自动注册3. 优先级 前言 沿用上一篇文章的流程图&#xff0c;我们的注解类应用上下文中的AnnotationConfigApplicationContext#scan(String...)方法已经将所有BeanDefinition注册到了IoC容器中。完成注册后&#xff0c;开始执行AbstractApplicatio…

信息的浏览

万维网(WWW)是目前Internet上最流行的一种服务&#xff0c;它是建立在Internet上的多媒体集合信息系统。它利用超媒体的信息获取技术&#xff0c;通过一种超文本的表达方式&#xff0c;将所有WWW上的信息连接在一起。我们使用浏览器浏览网上的信息。 ▶浏览器 浏览器是指可以…

PHP低版本安全问题

目录 1、PHP弱类型问题 1.1 MD5、 SHA1 弱比较问题 1.2 数组 0 1&#xff09;函数无法处理数组&#xff0c;返回0 2&#xff09;strcmp 2、特殊字符串导致的问题 2.1 "ffifdyop" 与 md5(string,raw) 2.2 ereg函数漏洞&#xff1a;00 截断 3、正则匹配问…

物联网AI MicroPython学习之语法UART通用异步通信

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; UART 介绍 模块功能: UART通过串行异步收发通信 接口说明 UART - 构建UART对象 函数原型&#xff1a;UART(id, baudrate&#xff0c;bits, parity&#xff0c;stop, tx, rx)参数说明&#xff1a; 参数类…

3GPP协议解读(一)_23.501_23.502_PDU Session_SMF与UDP的交互

UE发起计算服务申请后&#xff0c;网络侧处理的流程 UE发起服务的流程&#xff1a;service request网络侧处理服务涉及的通信数据通过PDU Session进行传输&#xff0c;涉及到SMF与UPF的交互。PDU Session的建立、管理全部由SMF&#xff08;Session Management Function&#x…