今天我们聊聊C#的并发和并行

并发和并行是现代编程中的两个重要概念,它们可以帮助开发人员创建高效、响应迅速、高性能的应用程序。在C#中,这些概念尤为重要,因为该语言提供了对多线程和异步编程的强大支持。本文将介绍C#中并发和并行编程的关键概念、优点,并结合WinForms提供实用示例。

并发

在C#中,并发是指同时管理多个任务。它使程序能够在重叠的时间里处理多个操作,创建响应迅速的应用程序。并发通常利用多线程和异步编程技术实现。

并行

并行是指同时执行多个任务。通常通过将一个问题划分为可并行处理的较小子问题来实现,并利用多个CPU核心进行处理。并行可以显著提高计算密集型任务的性能。

C#中并发和并行编程的关键概念

线程

线程是并发编程中的基本执行单元。在C#中,可以使用System.Threading命名空间来创建和管理线程。

异步编程

C#中的异步编程主要通过asyncawait关键字来支持,使方法可以异步运行,从而更好地利用系统资源并提升响应速度。

并行编程

C#中的并行编程由System.Threading.Tasks命名空间提供支持,其中包括Parallel类和任务并行库(TPL),用于创建和管理并行任务。

示例:C# WinForms中的并发和并行编程

下面的示例展示了如何在C# WinForms中实现并发和并行编程。我们将创建一个简单的程序,该程序执行两个任务:读取文件和进行CPU密集型计算。

步骤1:创建WinForms项目

首先,在你的首选开发环境中创建一个新的C# WinForms项目。

步骤2:使用异步编程实现并发

我们将使用异步编程来读取文件,并确保在文件读取期间不会阻塞主线程。

using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;namespace ConcurrencyExample
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private async void btnReadFile_Click(object sender, EventArgs e){lblStatus.Text = "开始读取文件...";// 开始异步文件读取操作Task<string> readFileTask = ReadFileAsync("example.txt");// 在读取文件时执行其他操作for (int i = 0; i < 10; i++){lblStatus.Text = $"执行其他任务... {i}";await Task.Delay(500); // 模拟其他任务}// 等待文件读取操作完成string fileContent = await readFileTask;lblFileContent.Text = fileContent;lblStatus.Text = "文件读取完成。";}private async Task<string> ReadFileAsync(string filePath){using (StreamReader reader = new StreamReader(filePath)){return await reader.ReadToEndAsync();}}}
}

步骤3:使用Parallel类实现并行

接下来,我们将展示如何使用Parallel类来执行并行的CPU密集型计算。

using System;
using System.Threading.Tasks;
using System.Windows.Forms;namespace ParallelExample
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void btnParallelComputation_Click(object sender, EventArgs e){lblStatus.Text = "开始并行计算...";// 执行并行计算Parallel.For(0, 10, i =>{PerformComputation(i);});lblStatus.Text = "并行计算完成。";}private void PerformComputation(int index){// 模拟CPU密集型计算double result = 0;for (int i = 0; i < 1_000_000; i++){result += Math.Sqrt(i + index);}this.Invoke((MethodInvoker)delegate {lstResults.Items.Add($"索引 {index} 的计算结果: {result}");});}}
}

应用场景

用户界面的响应性

在图形用户界面(GUI)应用程序中,例如WinForms或WPF,保持用户界面的响应性至关重要。繁重的任务如文件读取、网络请求或者图像处理可能会拖慢主线程,导致用户界面卡顿。通过使用异步编程,这些任务可以在后台运行,不会阻塞主线程,从而保持界面流畅、响应迅速。

private async void btnFetchData_Click(object sender, EventArgs e)
{lblStatus.Text = "Fetching data...";var data = await FetchDataAsync("http://example.com/api/data");lblStatus.Text = "Data fetched!";txtData.Text = data;
}private async Task<string> FetchDataAsync(string url)
{using (HttpClient client = new HttpClient()){return await client.GetStringAsync(url);}
}

大数据处理和分析

在处理大量数据或执行复杂的数据分析任务时,使用并行编程可以显著提高性能。通过将数据分割成更小的部分,并使用多个线程并行处理,可以加速处理速度。

private void btnProcessData_Click(object sender, EventArgs e)
{lblStatus.Text = "Processing data...";double[] results = new double[10];Parallel.For(0, 10, i =>{results[i] = PerformComputation(i);});lstResults.Items.AddRange(results.Select(r => r.ToString()).ToArray());lblStatus.Text = "Data processed.";
}private double PerformComputation(int index)
{double sum = 0;for (int i = 0; i < 1_000_000; i++){sum += Math.Sqrt(i + index);}return sum;
}

多任务执行

在许多应用中,需要同时执行多个独立的任务,例如多个传感器的数据读取、多个文件的并行上传或多个用户请求的同时处理。并发编程可以有效管理这些任务,确保系统资源得到充分利用。

private async void btnUploadFiles_Click(object sender, EventArgs e)
{lblStatus.Text = "Uploading files...";var tasks = selectedFiles.Select(file => UploadFileAsync(file)).ToArray();await Task.WhenAll(tasks);lblStatus.Text = "All files uploaded!";
}private async Task UploadFileAsync(string filePath)
{// 具体上传与其它专业await Task.Delay(1000);
}

实时系统

在实时系统中,例如导航系统、工业控制系统或金融交易系统,并发和并行技术可以确保实时响应和高效处理多个任务。通过合理分配任务,可以提升系统的实时性和稳定性。

private void btnStartProcessing_Click(object sender, EventArgs e)
{lblStatus.Text = "Processing sensors data...";Parallel.ForEach(sensors, sensor =>{ProcessSensorData(sensor);});lblStatus.Text = "Data processed.";
}private void ProcessSensorData(Sensor sensor)
{// 业务Task.Delay(500).Wait();
}

结论

并发和并行是提高应用程序性能和响应速度的强大工具。在C#中,通过异步编程和任务并行库很好地支持了这些概念。通过利用这些技术,开发人员可以创建能有效管理多个任务并利用系统资源的应用程序。本文提供的示例展示了如何在C# WinForms应用程序中实现并发和并行编程,为创建更复杂和更具可扩展性的应用程序奠定了基础。

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

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

相关文章

如何使用录屏软件录制声音?超实用的4个电脑录屏方法!

在现代的数字时代&#xff0c;录屏软件已经成为我们日常工作和学习中不可或缺的工具之一。无论是制作教学视频、演示软件功能&#xff0c;还是记录游戏过程&#xff0c;录屏软件都能提供极大的帮助。但许多人在使用录屏软件时&#xff0c;可能会遇到一个问题&#xff1a;如何将…

Godot游戏制作 03世界构建1.0版

在game场景&#xff0c;删除StaticBody2D节点&#xff0c;添加TileMap节点 添加TileSet图块集 添加TileSet源 拖动图片到图块&#xff0c;自动创建图块 使用橡皮擦擦除。取消橡皮擦后按住Shift创建大型图块。 进入选择模式&#xff0c;TileMap选择绘制&#xff0c;选中图块后在…

Leetcode 721.账户合并(hash+dfs)☆

思路&#xff1a; 最核心的地方在于如何合并&#xff1f;这里是通过具有相同的email进行账户的合并&#xff0c;这个相同的email类似于图中的共同节点将两个账户连接起来&#xff0c;所以将原来 账户名 -> 邮件1 邮件2.。。变成hash 邮件1 ->账户id1&#xff0c;账户id2…

Meta革命性发布:Llama 3.1——性能最强的AI开源模型,开启智能新时代!

前言 &#x1f680; Meta隆重推出Llama 3.1&#xff1a;迄今为止性能最强的AI模型 Meta公司近日发布了他们最新的AI语言模型——Llama 3.1&#xff0c;这一消息迅速在科技界掀起了波澜。作为猫头虎技术团队&#xff0c;我们将为大家详细解析Llama 3.1的强大功能及其应用前景。…

Android APP 音视频(02)MediaProjection录屏与MediaCodec编码

说明&#xff1a; 此MediaProjection 录屏和编码实操主要针对Android12.0系统。通过MediaProjection获取屏幕数据&#xff0c;将数据通过mediacodec编码输出H264码流&#xff08;使用ffmpeg播放&#xff09;&#xff0c;存储到sd卡上。 1 MediaProjection录屏与编码简介 这里…

HTML5 + CSS3

HTML 基础 准备开发环境 1.vscode 使用 新建文件夹 ---> 左键拖入 vscode 中 2.安装插件 扩展 → 搜索插件 → 安装打开网页插件&#xff1a;open in browser汉化菜单插件&#xff1a;Chinese 3.缩放代码字号 放大,缩小&#xff1a;Ctrl 加号&#xff0c;减号 4.设…

机械设计基础B(学习笔记)

绪论 机构&#xff1a;是一些具备各自特点的和具有确定的相对运动的基本组合的统称。 组成机构的各个相对运动部分称为构件。构件作为运动单元&#xff0c;它可以是单一的整体&#xff0c;也可以是由几个最基本的事物&#xff08;通常称为零件&#xff09;组成的刚性结构。 构件…

华杉研发九学习日记17 正则表达式 异常

华杉研发九学习日记17 一&#xff0c;正则表达式 ^ $ 作用&#xff1a; 测试字符串内的模式(匹配) 例如&#xff0c;可以测试输入字符串&#xff0c;以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证. 替换文本&#xff08;替换》 可以使用正则表达式来…

vue3 学习笔记17 -- 基于el-menu封装菜单

vue3 学习笔记17 – 基于el-menu封装菜单 前提条件&#xff1a;组件创建完成 配置路由 // src/router/index.ts import { createRouter, createWebHashHistory } from vue-router import type { RouteRecordRaw } from vue-router export const Layout () > import(/lay…

PyTorch 2.0 GPU Nvidia运行库的安装

【图书推荐】《PyTorch深度学习与计算机视觉实践》-CSDN博客 假设读者电脑带有NVIDIA 20 以上系列的显卡。 我们以CUDA 11.7cuDNN 8.2.0&#xff08;其他更高版本的组合&#xff0c;读者可以执行查阅PyTorch官网获得&#xff09;为例&#xff0c;讲解PyTorch 2.0 GPU版本的安…

rt_container_of 作用和实现过程超级详解介绍

目录 作用 ptr 获取 偏移size获取 函数作用 我们先看段代码,了解rt_container_of有什么用处&#xff1a; #include "stdio.h" #define rt_container_of(ptr, type, member) \((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))struct ST…

Chrome谷歌浏览器Console(控制台)显示文件名及行数

有没有这样的困扰&#xff1f;Chrome谷歌浏览器console(控制台)不显示编译文件名及行数? 设置&#xff08;Settings&#xff09;- > 忽略列表&#xff08;lgnore List&#xff09;-> 自定义排除规则&#xff08;Custom exclusion rules&#xff09; 将自定义排除规则…

昇思学习打卡-22-生成式/DCGAN生成漫画头像

文章目录 DCGAN网络数据处理构造网络生成器判别器损失函数优化器 结果展示 我们将学习DCGAN网络如何数据处理、设置网络&#xff0c;包括生成器、判别器、损失函数、优化器等。 DCGAN网络 DCGAN&#xff08;深度卷积对抗生成网络&#xff0c;Deep Convolutional Generative Ad…

go-kratos 学习笔记(1) 安装

简介&#xff1a; Kratos 一套轻量级 Go 微服务框架&#xff0c;包含大量微服务相关框架及工具。 使用步骤&#xff1a; 安装cli工具 go install github.com/go-kratos/kratos/cmd/kratos/v2latest 创建项目 通过 kratos 命令创建项目模板 # 国内拉取失败可使用gitee源 krat…

项目实战--C#实现图书馆信息管理系统

本项目是要开发一个图书馆管理系统&#xff0c;通过这个系统处理常见的图书馆业务。这个系统主要功能是&#xff1a;&#xff08;1&#xff09;有客户端&#xff08;借阅者使用&#xff09;和管理端&#xff08;图书馆管理员和系统管理员使用&#xff09;。&#xff08;2&#…

Mac装虚拟机占内存吗 Mac用虚拟机装Windows流畅吗

如今&#xff0c;越来越多的Mac用户选择在他们的设备上安装虚拟机来运行不同的操作系统。其中&#xff0c;最常见的是使用虚拟机在Mac上运行Windows。然而&#xff0c;许多人担心在Mac上装虚拟机会占用大量内存&#xff0c;影响电脑系统性能。此外&#xff0c;有些用户还关心在…

C++实现LRU缓存(新手入门详解)

LRU的概念 LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;是一种常用的缓存淘汰策略&#xff0c;主要目的是在缓存空间有限的情况下&#xff0c;优先淘汰那些最长时间没有被访问的数据项。LRU 策略的核心思想是&#xff1a; 缓存空间有限&#xff1…

Linux:传输层(2) -- TCP协议(1)

目录 1. TCP协议段格式 2. 解包/分用 3. 确认应答(ACK)机制 4. 超时重传机制 5. 连接管理机制 5.1 三次握手 5.2 四次挥手 5.3 TIME_WAIT状态 5.4 CLOSE_WAIT状态 1. TCP协议段格式 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去; 32位序号/32位确认号: 后面详…

FreeModbus学习——读输入寄存器eMBFuncReadInputRegister

FreeModbus版本&#xff1a;1.6 当功能码为04时&#xff0c;也就是读输入寄存器MB_FUNC_READ_INPUT_REGISTER 看一下它是怎么调用读输入寄存器处理函数的 当功能码为04时&#xff0c;调用读输入寄存器处理函数 这个函数在数组xFuncHandlers中&#xff0c;也就是eMBFuncRead…

实战:MyBatis适配多种数据库:MySQL、Oracle、PostGresql等

概叙 很多时候&#xff0c;一套代码要适配多种数据库&#xff0c;主流的三种库&#xff1a;MySQL、Oracle、PostGresql&#xff0c;刚好mybatis支持这种扩展&#xff0c;如下图所示&#xff0c;在一个“namespace”&#xff0c;判断唯一的标志是iddatabaseId&#xff0c;刚好写…