在很多情況下,我們的任務前後之間沒有必然的聯系的,所以我們可以不需要等待前面命令結束,才開始後面的任務。我們可以多個任務並行運行,這就是異步編程。
首先我們先來看一個常規的程序:
using System;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
namespace ConsoleApp30
{
class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew(); // 统计程序运行的时间
Ping ping = new Ping();
String NetNumber = "192.168.0.";
int[] HosNumer = Enumerable.Range(1, 254).ToArray();
foreach( int i in HosNumer )
{
string IP = NetNumber + i;
PingReply pingReply = ping.Send($"{IP}");
if(pingReply.Status == IPStatus.Success)
{
Console.WriteLine($"The IP {IP} ping is pass.");
}
else
{
Console.WriteLine($"The IP {IP} ping is failed.");
}
}
Console.WriteLine($"Time is {stopwatch.ElapsedMilliseconds}");
}
}
}
这是一个 ping 程序,它会 ping 指定的 IP 的地址的状态,并返回结果。
運行結果:
The IP 192.168.0.1 ping is pass.
The IP 192.168.0.2 ping is failed.
The IP 192.168.0.3 ping is failed.
The IP 192.168.0.4 ping is failed.
The IP 192.168.0.5 ping is failed.
......
......
The IP 192.168.0.252 ping is failed.
The IP 192.168.0.253 ping is failed.
The IP 192.168.0.254 ping is failed.
Time is 751872 // 程序运行的时间
使用異步的方式:
using System;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace ConsoleApp30
{
class Program
{
static async Task Main(string[] args) // 这里要使用 async
{
Stopwatch stopwatch = Stopwatch.StartNew(); // 统计程序运行的时间
Ping ping = new Ping();
String NetNumber = "192.168.0.";
int[] HosNumer = Enumerable.Range(1, 254).ToArray();
foreach( int i in HosNumer )
{
string IP = NetNumber + i;
// 添加 await, 并且使用 ping 的方式也有所不同
PingReply pingReply = await ping.SendPingAsync($"{IP}");
if(pingReply.Status == IPStatus.Success)
{
Console.WriteLine($"The IP {IP} ping is pass.");
}
else
{
Console.WriteLine($"The IP {IP} ping is failed.");
}
}
Console.WriteLine($"Time is {stopwatch.ElapsedMilliseconds}");
}
}
}
運行結果:
The IP 192.168.0.1 ping is pass.
The IP 192.168.0.2 ping is failed.
The IP 192.168.0.3 ping is failed.
The IP 192.168.0.4 ping is failed.
The IP 192.168.0.5 ping is failed.
......
......
The IP 192.168.0.250 ping is failed.
The IP 192.168.0.251 ping is failed.
The IP 192.168.0.252 ping is failed.
The IP 192.168.0.253 ping is failed.
The IP 192.168.0.254 ping is failed.
Time is 438322
這次測試,所花費的時間,比之前少了很多。
PingReply pingReply = await ping.SendPingAsync($"{IP}");
這樣結果其實跟同步沒什麼不同
都是要等待結果後才能做其他事
非同步可能像下面這樣會比較有感
var pingReplyTask = ping.SendPingAsync($"{IP}"); // 0:00 假設這Method要花上10秒才能取得結果
Other Code......//0:00~0:10 等待結果期間可以做其他事情
PingReply pingReply = await pingReplyTask;//0:10 取得結果
這個例子做成非同步會是像這樣
using System;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace ConsoleApp30
{
class Program
{
static async Task Main(string[] args) // 这里要使用 async
{
Stopwatch stopwatch = Stopwatch.StartNew(); // 统计程序运行的时间
String NetNumber = "127.0.0.";
int[] HosNumer = Enumerable.Range(1, 254).ToArray();
List<Task> tasks = new List<Task>();
foreach (int i in HosNumer)
{
tasks.Add(Task.Run(async () =>
{
string IP = NetNumber + i;
Ping ping = new Ping();
// 添加 await, 并且使用 ping 的方式也有所不同
PingReply pingReply = await ping.SendPingAsync($"{IP}");
if (pingReply.Status == IPStatus.Success)
{
Console.WriteLine($"The IP {IP} ping is pass.");
}
else
{
Console.WriteLine($"The IP {IP} ping is failed.");
}
}));
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine($"Time is {stopwatch.ElapsedMilliseconds}");
}
}
}
但由於非同步的Method本來就很快了 沒什麼要等的 所以基本上沒差