c#多线程同步执行

技术博客 (244) 2023-09-16 16:26:01

对于多线程同步执行,可能听起来比较拗口,但是它的作用在某些业务下,有非常的大作用,分别进行阐述。

同步

同步就是按照顺序1234这样进行下去,有顺序,有规律的进行着。

多线程

多线程对于单线程来说的,单线程,就是开启一个线程进行工作,多线程则是,开启多个线程进行多个工作,并且没有顺序,没有规律性。

多线程同步,则是,既有同步和多线程的特点,即开启多个线程进行工作的同时,还要按照顺序和规律执行。

其实,解决多线性同步的问题,有很多种,比如使用lock锁等等方法。本节介绍使用async/await的方法来实现他的功能。

1.建立一个winform程序,可以模拟界面处理数据

c#多线程同步执行 (https://mushiming.com/) 技术博客 第1张

2.使用同步的方法

对变量a增加1,其中 Thread.Sleep(1000)可以表示,这个业务处理的时间,然后连续增加5次。

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        int a = 0;
        public Form1()
        {
            InitializeComponent();
        }
        private  void button1_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            A();
            //Task.Delay(3000);
            //B();
            //Task.Delay(3000);
            //await  C();
            stopwatch.Stop();
            label1.Text = a.ToString();
            label2.Text = "耗时:" + stopwatch.ElapsedMilliseconds;

            //Thread.Sleep(10000);
        }
        /// <summary>
        /// 单线程,同步有顺序
        /// </summary>
        public void A()
        {
            a++;
            Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);
        }
        /// <summary>
        /// 多线程,并行,没有顺序
        /// </summary>
        public void B()
        {

            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });

            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });

            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });


            //List<Task> tasks = new List<Task>();


            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //Task.WaitAll(tasks.ToArray());
        }

        /// <summary>
        /// 多线程,并行,有顺序
        /// </summary>
        /// <returns></returns>
        public async Task C()
        {
            Task task = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task;
            Task task1 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task1;

            Task task2 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task2;

            Task task3 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task3;

            Task task4 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task4;
        }


    }
}

效果

c#多线程同步执行 (https://mushiming.com/) 技术博客 第2张

耗时5036,按照顺序执行,并且界面是卡死状态。

3.使用多线程的方法

因为变化太快了,所以增加了延迟

多线程,还可以使用B()中屏蔽的方法

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        int a = 0;
        public Form1()
        {
            InitializeComponent();
        }
        private  void button1_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            //A();
            Task.Delay(3000);
            B();
            Task.Delay(3000);
            //await  C();
            stopwatch.Stop();
            label1.Text = a.ToString();
            label2.Text = "耗时:" + stopwatch.ElapsedMilliseconds;

            //Thread.Sleep(10000);
        }
        /// <summary>
        /// 单线程,同步有顺序
        /// </summary>
        public void A()
        {
            a++;
            Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);
        }
        /// <summary>
        /// 多线程,并行,没有顺序
        /// </summary>
        public void B()
        {
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });

            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });

            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });


            //List<Task> tasks = new List<Task>();


            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //Task.WaitAll(tasks.ToArray());
        }

        /// <summary>
        /// 多线程,并行,有顺序
        /// </summary>
        /// <returns></returns>
        public async Task C()
        {
            Task task = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task;
            Task task1 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task1;

            Task task2 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task2;

            Task task3 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task3;

            Task task4 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task4;
        }


    }
}

效果 

c#多线程同步执行 (https://mushiming.com/) 技术博客 第3张

耗时29,可以看到没有按照顺序进行,但是界面是可以移动的

4. 多线程同步

这段代码就阐述了,即开启多个线程进行工作的同时,还按照顺序和规律执行。

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        int a = 0;
        public Form1()
        {
            InitializeComponent();
        }
        private async void button1_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            //A();
            //Task.Delay(3000);
            //B();
            //Task.Delay(3000);
            await  C();
            stopwatch.Stop();
            label1.Text = a.ToString();
            label2.Text = "耗时:" + stopwatch.ElapsedMilliseconds;

            //Thread.Sleep(10000);
        }
        /// <summary>
        /// 单线程,同步有顺序
        /// </summary>
        public void A()
        {
            a++;
            Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);

            a++; Console.WriteLine(a);
            Thread.Sleep(1000);
        }
        /// <summary>
        /// 多线程,并行,没有顺序
        /// </summary>
        public void B()
        {
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });

            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });

            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });
            Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(10000);
            });


            //List<Task> tasks = new List<Task>();


            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //tasks.Add(Task.Run(() =>
            //{
            //    a++;
            //    Console.WriteLine(a);
            //    Thread.Sleep(1000);
            //}));

            //Task.WaitAll(tasks.ToArray());
        }

        /// <summary>
        /// 多线程,并行,有顺序
        /// </summary>
        /// <returns></returns>
        public async Task C()
        {
            Task task = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task;
            Task task1 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task1;

            Task task2 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task2;

            Task task3 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task3;

            Task task4 = Task.Run(() =>
            {
                a++;
                Console.WriteLine(a);
                Thread.Sleep(1000);
            });
            await task4;
        }


    }
}

 效果

c#多线程同步执行 (https://mushiming.com/) 技术博客 第4张

耗时5052,并且是按照顺序执行的,而且界面还可以拖动,正是我们需要的。 

拓展async/await

在C()方法中,其实是遇到await后,代码则是返回task.run上面去了,然后从上到下再执行,执行到第二方法,又返回task.run上面去了,然后再从上到下执行,以此类推,所以和同步执行的时间基本上一样的。

THE END

发表回复