c# 高并发的几种方式(三)

427 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情 

之前的章节中,我们介绍了两种并发模式。一种是actor模型编程,一种是异步编程。本章节,我们主要介绍另外一种并发编程方法:并行编程。

简介

.net中包含有并行编程的核心库。再.net4中引入,名为Task Parallel Library(任务并行库),简称TPL。任务并行库主要可用于三个使用场景:

  • 数据并行
    何为数据并行呢:数据并行的场景是需要处理大量的数据,并且这些原始数据需要通过一个复杂的计算过程,并且计算过程都是一样的。这种场景下,可以使用数据并行。

  • 任务并行 何为任务并行呢:任务并行是指同一时间,需要处理很多的操作,这些操作各不相同,并且每个操作之间的耦合性低,相互独立,这种场景下,可以使用任务并行。

  • 流水线 何为流水线呢:通过上面两个场景,如果存在大量的数据&&这些数据需要进行的处理不相同&数据处理起来还有耦合性,这种情况就要用到流水线编程,流水线编程是数据并行和任务并行的结合,并且还要高端那么一点点,因为数据之间还有耦合性。

TPL 类

System.Threading.Tasks.Parallel类

  • parallel.for 为拱顶数据的独立for玄幻迭代提供并行执行,根据这个解释,是不是适合数据并发场景

  • parallel.foreach 为固定数据的独立foreach循环提供并行执行,这个方法支持自定义分区器,因此,我们可以掌控数据的分发。本释义,也说明是适用于数据并发场景

  • parallel.involke 为给定的独立任务提供并行执行,明了的告诉我们,适用于任务并发场景。

丐版 demo

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TPLInvolkeDemo
{
    internal class Program
    {
        /// <summary>
        /// 任务1
        /// </summary>
        private static void Task1()
        {
            Console.WriteLine($"Task1:---->{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
        }
        /// <summary>
        /// 任务2
        /// </summary>
        private static void Task2()
        {
            Thread.Sleep(1);
            Console.WriteLine($"Task2:---->{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
        }
        /// <summary>
        /// 任务3
        /// </summary>
        private static void Task3()
        {
            Thread.Sleep(3);
            Console.WriteLine($"Task3:---->{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
        }
        /// <summary>
        /// 任务4
        /// </summary>
        private static void Task4()
        {
            Console.WriteLine($"Task4:---->{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
        }
        /// <summary>
        /// main
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("Here We Go !");
            Parallel.Invoke(() => Task1(), () => Task2(), () => Task3(), () => Task4());
            Console.ReadLine();
        }
    }
}

效果

image.png

注意:当我们运行这四个task的时候,这里我们加了sleep延时,可能会看起来像是有有顺序。事实上是:我们无法准确的预测其执行顺序,因为这一切是由底层的逻辑会根据运行时的现有可用资源创建出最合适的执行。
tpl也有办法可以保证运行的顺序,不过这里我们不过讨论,因为我们是丐版demo。Over!