异步多线程之Parallel详解_paralleloptions-程序员宅基地

技术标签: c#  多线程  .Net  .net  

上一篇:异步多线程之入Task
下一篇:异步多线程使用中的常见问题


简介

Parallel 叫做并行编程 .Net 4.5 时代的,基于 Task 基础上做了封装。Parallel 的特点方便控制线程并发数量与节省一个线程。

API

Parallel 相对来说也比较简单,这里介绍几个 API(Invoke、For、ForEach)的用法,这三个 API 都可以节约一个线程。

Invoke

例如:Invoke 方法可以做并发,传入委托即可。这里并发 3 任务,如下

public static void Coding(string name, string module)
{
    
    Console.WriteLine($"{
      name} Coding Start {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.WriteLine($"{
      name} Coding End  {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");
}

static void Main(string[] args)
{
    
    Console.WriteLine($"Main Start,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Parallel.Invoke(() => Coding("张三", "Web"), () => Coding("李四", "Service"), () => Coding("王五", "SQL"));

    Console.WriteLine($"Main End,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.ReadLine();
}

启动程序,可以看到 3 个任务并发执行,会卡界面。但只有三个线程(1-主线程,3、4-子线程),节约一个线程。
在这里插入图片描述

For

For 也是一样的,主线程参与计算,节约一个线程。

public static void Coding(string name, string module)
{
    
    Console.WriteLine($"{
      name} Coding Start {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.WriteLine($"{
      name} Coding End  {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");
}

static void Main(string[] args)
{
    
    Console.WriteLine($"Main Start,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Parallel.For(0, 5, i =>
    {
    

        Coding("张三"+ i.ToString(), "Web" + i.ToString());
    });

    Console.WriteLine($"Main End,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.ReadLine();
}

在这里插入图片描述
在这里插入图片描述

ForEach

For 也是一样的,主线程参与计算,节约一个线程。

public static void Coding(string name, string module)
{
    
    Console.WriteLine($"{
      name} Coding Start {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.WriteLine($"{
      name} Coding End  {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");
}

static void Main(string[] args)
{
    
    Console.WriteLine($"Main Start,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Parallel.ForEach(new int[] {
     2, 4, 6, 8 }, i =>
        {
    
            Coding("张三" + i.ToString(), "Web" + i.ToString());
        });

    Console.WriteLine($"Main End,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.ReadLine();
}

在这里插入图片描述

限定线程数量

Parallel 限定线程数量也是比较简单的,使用 ParallelOptions 设置一下即可。如下

public static void Coding(string name, string module)
{
    
    Console.WriteLine($"{
      name} Coding Start {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.WriteLine($"{
      name} Coding End  {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");
}

static void Main(string[] args)
{
    
    Console.WriteLine($"Main Start,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    ParallelOptions parallelOptions = new ParallelOptions();
    parallelOptions.MaxDegreeOfParallelism = 3;
    Parallel.For(0, 10, parallelOptions, i =>
    {
    

        Coding("张三" + i.ToString(), "Web" + i.ToString());
    });

    Console.WriteLine($"Main End,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.ReadLine();
}

在这里插入图片描述

如何不卡线程?答案:还是老套路,包一层。如下

public static void Coding(string name, string module)
{
    
    Console.WriteLine($"{
      name} Coding Start {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.WriteLine($"{
      name} Coding End  {
      module},ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");
}

static void Main(string[] args)
{
    
    Console.WriteLine($"Main Start,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Task.Run(() =>
    {
    
        ParallelOptions parallelOptions = new ParallelOptions();
        parallelOptions.MaxDegreeOfParallelism = 3;
        Parallel.For(0, 10, parallelOptions, i =>
        {
    
            Coding("张三" + i.ToString(), "Web" + i.ToString());
        });
    });

    Console.WriteLine($"Main End,ThreadId:{
      Thread.CurrentThread.ManagedThreadId},Datetime:{
      DateTime.Now.ToLongTimeString()}");

    Console.ReadLine();
}

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46785144/article/details/121135153

智能推荐

【Python学习】下载faceScrub人脸数据库 (多线程版本)_facescrub download-程序员宅基地

文章浏览阅读6.8k次,点赞4次,收藏2次。在上一篇博文中,我用单线程版本的Python来实现下载脚本,其中最大的不足在于它是单线程的,很慢。其实,下载网络图片是天然的具有并行性的,因为下载每一副图片都是独立的,甚至线程之间都不用交互。 -*- coding: utf-8 -*-"""Created on Tue Apr 07 20:19:38 2015@author: Chenriwei"""impo_facescrub download

eclipse导出jar包的问题总结_无法导出.jar 权限不够-程序员宅基地

文章浏览阅读1.1k次。eclipse各种打包方式第一种解决方案Copy requeired libraries libraries into a sub-forder next to the generated JAR选用这个选项,eclipse生成的jar包1.把自己写应用打成一个jar包,如:test.jar2.创建一个文件夹与该jar包同名并在其后面加"_lib",如:test_lib3._无法导出.jar 权限不够

CMWAP和CMNET的区别-程序员宅基地

文章浏览阅读586次。 有的朋友可能遇到这样的尴尬,办了个手机上网套餐结果一查详单上网费高的惊人。实际上就移动包月套餐来说一般指的是CMWAP方式的流量。我查询了些资料写一下两者的区别。 如果你对该部分没有任何兴趣,你可以这样理解:用普通手机(非智能手机,支持GPRS)上网就是CMWAP;用智能手机/手机连接电脑/移动专用双模网卡上网即CMNET/WLAN方式1.WAP GPRS WLAN CSDWAP(Wir_cmwap和cmnet的区别

Pixhawk_Ardupilot编译环境_Ubuntu_ubuntu20.04 pixhawk ardupilot 编译环境-程序员宅基地

文章浏览阅读4.3k次。Pixhawk_Ardupilot编译环境_Ubuntu本文是官网站的翻译!QQ:4862879Ubuntu的安装这里不讲,不会的自己去网上找吧!提前准备:经常出错的地方是运行安装脚本 这块,主要是 gcc-arm cross-compiler下载速度较慢,gcc-arm cross-compiler 点击下载可以提前下载好后先安装:tar _ubuntu20.04 pixhawk ardupilot 编译环境

关于最近抖音上很火的,给女友的相册的源代码_女友相册源码-程序员宅基地

文章浏览阅读3.1k次,点赞5次,收藏9次。关于最近抖音上很火的,给女友的相册的源代码<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <audio autoplay="autoplay" controls="controls" loop="loop" preload="auto" src="改为你自己的音乐文件名"> 你的浏览器版本太低,不支持audio标签 <_女友相册源码

高科技:人工智能视频换脸,朱茵变杨幂,毫无违和感-程序员宅基地

文章浏览阅读7.8k次,点赞4次,收藏6次。近日,一条名为“将朱茵的黄蓉换成杨幂的脸”的话题在网上引起了很大的讨论。很多人不解什么叫把朱茵的黄蓉要换成杨幂?难道杨幂要怕《射雕英雄传》了?并没有!原来,有网友在利用现在先进的AI技术...

随便推点

EASY UI tree如何根据部分值来选中checkbox_ftvedos-程序员宅基地

文章浏览阅读7.1w次。首先tree需要设置checkbox:true _ftvedos

Markdown自定义CSS样式_markdown css-程序员宅基地

文章浏览阅读5.8k次。前言当我第一次接触到Markdown时,我就深深爱上了它。这简洁的界面,编程式的书写都令我爱不释手,最重要的是,还能够支持自定义html、css。自定义CSS样式说到Markdown,就不得不提及Typora这个软件,本例子即是在此软件的环境下完成。想要自定义CSS,首先得有一定的htm,css基础。1.寻找Typora的主题CSS文件确认typora软件用的主题文件 -> 外观 -> 打开主题文件 -> 找到对应的css文件,因为我用的主题是Night,所以我应该找nigh_markdown css

Python PEP8 命名规范_在python中,哪种变量命名方式是符合pep 8标准的-程序员宅基地

文章浏览阅读2.7k次。https://blog.csdn.net/ratsniper/article/details/78954852#class-names-%E7%B1%BB%E5%90%8D_在python中,哪种变量命名方式是符合pep 8标准的

将pycharm打印出来的东西保存到txt_pycharm 如何下载打印的数据-程序员宅基地

文章浏览阅读2.7k次。因为特殊需要需要把打印的东西保存下来,因此记笔记:# 创建一个txt文件,文件名为save_result.txtdef text_create(name): # 此处是服务器地址,可以改为本地 desktop_path = "/home/xxx/GraphNN/" # 新创建的txt文件的存放路径 full_path = desktop_path + name + '.txt' # 也可以创建一个.doc的word文档 file = open(full_path_pycharm 如何下载打印的数据

新思科技调查:提升软件质量与安全性是开发人员的首要关注点_员工对软件质量的改进和对项目稳定性、安全性的重要贡献-程序员宅基地

文章浏览阅读347次。在软件开发过程中,软件质量管理、程序的正常运营以及应用程序的安全性等都需要专门的检测。在部分企业,这些工作由软件测试工程师来完成。不过目前在中国软件测试工程师的人才缺口仍然比较大。根据美国新思科技公司最新的一份调查,软件的质量与安全是开发人员最关注的两个指标。此外,缺乏熟练的专业人才和培训是全面实施软件安全计划(SSI)的最大挑战。近日,在TiD2018质量竞争力大会上,新思科技软件..._员工对软件质量的改进和对项目稳定性、安全性的重要贡献

【数据结构】单链表的相关操作--创建-插入-删除-查找_单链表插入结点失败-程序员宅基地

文章浏览阅读1.4k次,点赞3次,收藏5次。文章目录单链表的相关操作单链表的创建单链表的插入按位序插入指定结点的后插操作指定结点的前插操作单链表的删除按位序删除指定结点的删除单链表的查找按位查找按值查找单链表的相关操作单链表的创建关于带头结点与不带头结点,不带头结点表示指针指向的第一个结点就是要存放数据的结点,而带头结点表示指针指向的第一个结点内数据域不存任何数据,其指向的下一个结点才是存放数据的第一个结点。两者看似无区别,实际上区别很大:/*不带头结点*/typedef struct LNode { //定义单链表结点类型 Ele_单链表插入结点失败

推荐文章

热门文章

相关标签