线程与异步的使用方法
使用场景
-
方法 AAA, BBB, CCC
-
在主线程不阻塞的情况下运行不同的三个方法
-
方法CCC需要在方法AAA完成后执行
使用线程完成
因为方法 CCC 要等待方法 AAA 完成,所以需要一个线程同步事件。
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static EventWaitHandle CCClcok = new EventWaitHandle(false, EventResetMode.ManualReset);
static void Main()
{
Thread tha = new Thread(AAA);
Thread thb = new Thread(BBB);
Thread thc = new Thread(CCC);
tha.Start();
thb.Start();
thc.Start();
Console.WriteLine("等待所有任务完成!");
}
static void AAA()
{
int sec = 10;
while (sec >= 1)
{
Console.WriteLine("方法 AAA: {0} 秒", sec);
sec--;
Thread.Sleep(1000);
}
Console.WriteLine("方法 AAA 执行完成!");
CCClcok.Set();
}
static void BBB()
{
int sec = 5;
while (sec >= 1)
{
Console.WriteLine("方法 BBB: {0} 秒", sec);
sec--;
Thread.Sleep(1000);
}
}
static void CCC()
{
CCClcok.WaitOne();
int sec = 3;
while (sec >= 1)
{
Console.WriteLine("方法 CCC: {0} 秒", sec);
sec--;
Thread.Sleep(1000);
}
}
}
线程同步事件
false 表示事件为非终止状态,EventResetMode.ManualReset 表示手动重置此事件(EventWaitHandle)
static EventWaitHandle CCClcok = new EventWaitHandle(false, EventResetMode.ManualReset);
方法 AAA
CCClcok.Set() 将事件状态设为终止。被阻塞线程继续 (EventWaitHandle.Set)
static void AAA()
{
int sec = 10;
while (sec >= 1)
{
Console.WriteLine("方法 AAA: {0} 秒", sec);
sec--;
Thread.Sleep(1000);
}
Console.WriteLine("方法 AAA 执行完成!");
CCClcok.Set();
}
方法 BBB
无要求
static void BBB()
{
int sec = 5;
while (sec >= 1)
{
Console.WriteLine("方法 BBB: {0} 秒", sec);
sec--;
Thread.Sleep(1000);
}
}
方法 CCC
CCClcok.WaitOne() 阻止当前线程,直到当前 WaitHandle 收到信号。(继承自 WaitHandle)[^ 1 ]
[^ 1 ]: 如果方法 AAA 没有执行 CCClcok.Set() 这里会出现死锁
static void CCC()
{
CCClcok.WaitOne();
int sec = 3;
while (sec >= 1)
{
Console.WriteLine("方法 CCC: {0} 秒", sec);
sec--;
Thread.Sleep(1000);
}
}
Main函数
线程默认为前台线程(IsBackground),所有主线程会等待所有子线程结束 (Thread)
static void Main()
{
Thread tha = new Thread(AAA);
Thread thb = new Thread(BBB);
Thread thc = new Thread(CCC);
tha.Start();
thb.Start();
thc.Start();
Console.WriteLine("等待所有任务完成!");
}
执行结果
Microsoft (R) Visual C# Compiler version 4.8.3761.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reser
This compiler is provided as part of the Microsoft (R
方法 AAA: 10 秒
方法 BBB: 5 秒
等待所有任务完成!
方法 BBB: 4 秒
方法 AAA: 9 秒
方法 BBB: 3 秒
方法 AAA: 8 秒
方法 AAA: 7 秒
方法 BBB: 2 秒
方法 BBB: 1 秒
方法 AAA: 6 秒
方法 AAA: 5 秒
方法 AAA: 4 秒
方法 AAA: 3 秒
方法 AAA: 2 秒
方法 AAA: 1 秒
方法 AAA 执行完成!
方法 CCC: 3 秒
方法 CCC: 2 秒
方法 CCC: 1 秒
请按任意键继续. . .
使用异步完成
-
注意事项(async,await)
- async 方法内部没有 await 关键字将以同步方法运行
- await 必须出现在 async 方法内部
- await 接一个异步对象(必须是可等待的)
-
不能让主线程直接退出,无法查看后面运行结果!
Thread.Sleep(14000);
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
BBB();
CCC();
Console.WriteLine("等待所有任务完成!");
Thread.Sleep(14000);
}
static async Task AAA()
{
int sec = 10;
while (sec >= 1)
{
Console.WriteLine("方法 AAA: {0} 秒", sec);
sec--;
await Task.Delay(1000);
}
Console.WriteLine("方法 AAA 执行完成!");
}
static async void BBB()
{
int sec = 5;
while (sec >= 1)
{
Console.WriteLine("方法 BBB: {0} 秒", sec);
sec--;
await Task.Delay(1000);
}
}
static async void CCC()
{
await AAA();
int sec = 3;
while (sec >= 1)
{
Console.WriteLine("方法 CCC: {0} 秒", sec);
sec--;
await Task.Delay(1000);
}
}
}
方法 AAA
返回一个 Task 对象
static async Task AAA()
{
int sec = 10;
while (sec >= 1)
{
Console.WriteLine("方法 AAA: {0} 秒", sec);
sec--;
await Task.Delay(1000);
}
Console.WriteLine("方法 AAA 执行完成!");
}
方法 BBB
无需等待,可以不用返回 Task 对象
static async void BBB()
{
int sec = 5;
while (sec >= 1)
{
Console.WriteLine("方法 BBB: {0} 秒", sec);
sec--;
await Task.Delay(1000);
}
}
方法 CCC
无需等待,可以不用返回 Task 对象
使用 await 等待方法 AAA 执行完毕
static async void CCC()
{
await AAA();
int sec = 3;
while (sec >= 1)
{
Console.WriteLine("方法 CCC: {0} 秒", sec);
sec--;
await Task.Delay(1000);
}
}
执行结果
Microsoft (R) Visual C# Compiler version 4.8.3761
for C# 5
Copyright (C) Microsoft Corporation. All rights r
This compiler is provided as part of the Microsof
方法 BBB: 5 秒
方法 AAA: 10 秒
等待所有任务完成!
方法 BBB: 4 秒
方法 AAA: 9 秒
方法 BBB: 3 秒
方法 AAA: 8 秒
方法 BBB: 2 秒
方法 AAA: 7 秒
方法 BBB: 1 秒
方法 AAA: 6 秒
方法 AAA: 5 秒
方法 AAA: 4 秒
方法 AAA: 3 秒
方法 AAA: 2 秒
方法 AAA: 1 秒
方法 AAA 执行完成!
方法 CCC: 3 秒
方法 CCC: 2 秒
方法 CCC: 1 秒
请按任意键继续. . .