异步多线程之Parallel详解

x33g5p2x  于2021-12-19 转载在 其他  
字(4.5k)|赞(0)|评价(0)|浏览(472)

上一篇:异步多线程之入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();
}

相关文章