程序运行的时候是同步的 但是他在同步的时候遇到一个需要等待一段时间得到结果的代码段时 他就不会执行下面的代码 而是等待完成后在执行 但是这个代码段只是执行就可以了 和下面的程序段也没有什么冲突的地方 那么 这个时候可以开启新的线程去处理它
让主程序继续运行
每次遇到需要等待的一些方法 我一般是使用多线程进行处理
比如 new Thread(()=>{/}).start();
但是后来我喜欢用C#的Task(开启任务线程)
new Task(()=>{/}).start()
Task.Run(()=>{/});//官方推荐
Task.Factory.StarNew(()=>{});
那这两者有什么区别呢
new Thread()是开启一个一个陪伴程序到结束的线程
频繁的去new Thread()会消耗大量内存
而Task 是在线程池里面
使用完后会被回收 避免内存浪费
那什么是异步? 那当然是和同步不一样才叫异步
异步指的是让CPU暂时搁置当前请求的响应,处理下一个请求,当通过轮询或其他方式得到回调通知后,开始运行
看一个异步的例子
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AwaitWithAsync
{
class Program
{
static void Main(string[] args)
{
MyDownLoadString ds = new MyDownLoadString();
ds.DoRun();
Console.ReadKey();
}
class MyDownLoadString
{
Stopwatch sw = new Stopwatch();
public void DoRun()
{
const int LargeNumber = 60000000;
sw.Start();
// Task<int> 保存结果对象,后面t1.Result则是获取结果
Task<int> t1 = CountCharactersAsync(1, "http://www.microsoft.com");
Task<int> t2 = CountCharactersAsync(2, "http://www.illustratedcsharp.com");
//无需等待CountCharactersAsync执行完成
CountToALargeNumber(1, LargeNumber);
CountToALargeNumber(2, LargeNumber);
CountToALargeNumber(3, LargeNumber);
CountToALargeNumber(4, LargeNumber);
//t1.Result获取结果
Console.WriteLine("Chars in Call1:{0}", t1.Result);
Console.WriteLine("Chars in Call1:{0}", t2.Result);
}
private async Task<int> CountCharactersAsync(int id, string uriString)
{
WebClient wc = new WebClient();
Console.WriteLine("Call {0} start: {1:N0}ms ", id, sw.Elapsed.TotalMilliseconds);
string result = await wc.DownloadStringTaskAsync(new Uri(uriString));
Trace.TraceInformation("Taceing Async Call {0} @time:{1:N0}ms", id, sw.Elapsed.TotalMilliseconds);
Console.WriteLine("Call {0} completed: {1:N0}ms", id, sw.Elapsed.TotalMilliseconds);
return result.Length;
}
private void CountToALargeNumber(int id, int value)
{
for (long i = 0; i < value; i++) ;
Console.WriteLine("End CountToALargeNumber {0}: {1:N0}ms", id, sw.Elapsed.TotalMilliseconds);
}
}
}
}
当LargeNumber是60000000时 运行
可以看到程序并不是顺序执行的
在调用计算的中期 第二个异步方法就已经执行完成了
第一个异步方法最后才完成
因为await花费的时间不一样
连接不顺畅的时候 甚至出现了这样的情况
在没有得到回调通知前 他们都在等待着没有执行
其他的代码照常运作 等到回调成功后 才执行完成