对于多线程同步执行,可能听起来比较拗口,但是它的作用在某些业务下,有非常的大作用,分别进行阐述。
同步
同步就是按照顺序1234这样进行下去,有顺序,有规律的进行着。
多线程
多线程对于单线程来说的,单线程,就是开启一个线程进行工作,多线程则是,开启多个线程进行多个工作,并且没有顺序,没有规律性。
多线程同步,则是,既有同步和多线程的特点,即开启多个线程进行工作的同时,还要按照顺序和规律执行。
其实,解决多线性同步的问题,有很多种,比如使用lock锁等等方法。本节介绍使用async/await的方法来实现他的功能。
1.建立一个winform程序,可以模拟界面处理数据

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);
- }
- ///
- /// 单线程,同步有顺序
- ///
- 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);
- }
- ///
- /// 多线程,并行,没有顺序
- ///
- 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
tasks = new List(); -
-
- //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());
- }
-
- ///
- /// 多线程,并行,有顺序
- ///
- ///
- 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;
- }
-
-
- }
- }
效果

耗时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);
- }
- ///
- /// 单线程,同步有顺序
- ///
- 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);
- }
- ///
- /// 多线程,并行,没有顺序
- ///
- 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
tasks = new List(); -
-
- //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());
- }
-
- ///
- /// 多线程,并行,有顺序
- ///
- ///
- 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;
- }
-
-
- }
- }
效果

耗时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);
- }
- ///
- /// 单线程,同步有顺序
- ///
- 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);
- }
- ///
- /// 多线程,并行,没有顺序
- ///
- 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
tasks = new List(); -
-
- //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());
- }
-
- ///
- /// 多线程,并行,有顺序
- ///
- ///
- 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;
- }
-
-
- }
- }
效果

耗时5052,并且是按照顺序执行的,而且界面还可以拖动,正是我们需要的。
拓展async/await
在C()方法中,其实是遇到await后,代码则是返回task.run上面去了,然后从上到下再执行,执行到第二方法,又返回task.run上面去了,然后再从上到下执行,以此类推,所以和同步执行的时间基本上一样的。