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

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

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

并发

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

并行

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

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

线程

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

异步编程

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

并行编程

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应用程序中实现并发和并行编程,为创建更复杂和更具可扩展性的应用程序奠定了基础。

目录
相关文章
|
25天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
2天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
273 12
|
17天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
5天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
19天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
22天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2582 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
4天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
174 2
|
2天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
101 65
|
5天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
269 2
|
21天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1579 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码