书上看到一个Task.Yield例子,Task.Yield方法创建一个立即返回的awaitable。等待一个Yield可以让异步方法在执行后续的部分时返回到调用方法。可以理解为离开当前的消息队列,回到队列末尾,让处理器有时间处理其他任务。
Yield方法在GUI编程中非常的有用,可以中断大量的工作,让其他任务使用处理器。
看下面的代码:
static void Main(string[] args)
{
Task<int> value = FindSeriesSum(100000);
Debug.WriteLine("主线其他任务开始");
CountBig(10000);
CountBig(10001);
CountBig(10002);
Thread.Sleep(1000);
CountBig(10003);
Debug.WriteLine("Length =" + value.Result);
Console.ReadKey();
}
public static async Task<int> FindSeriesSum(int i1)
{
int sum = 0;
for (int i = 0; i < i1; i++)
{
sum += i1;
if (i % 20000 == 0)
{
//await Task.Yield();
Debug.WriteLine("i % 20000 :i=" + i);
}
}
WebClient wc = new WebClient();
Debug.WriteLine("开始下载任务");
string str =await wc.DownloadStringTaskAsync("https://github.com/");
return str.Length;
}
private static void CountBig(int p)
{
for (int i = 0; i < p; i++)
{
if (i == p - 1)
Debug.WriteLine("p =" + p);
}
}
在执行下载任务await wc.DownloadStringTaskAsync("https://github.com/")前进行了大量的CPU运算,那么线程会等到第一个await的时候才会异步执行CountBig(10000);
程序运行的结果如下:
i % 20000 :i=0
i % 20000 :i=20000
i % 20000 :i=40000
i % 20000 :i=60000
i % 20000 :i=80000
开始下载任务
主线其他任务开始
p =10000
p =10001
p =10002
p =10003
Length =52728
我们需要立即返回的awaitable,让程序执行其他的任务,去掉//await Task.Yield();前面的注释符,得到的结果如下:
i % 20000 :i=0
主线其他任务开始
p =10000
i % 20000 :i=20000
p =10001
p =10002
i % 20000 :i=40000
i % 20000 :i=60000
i % 20000 :i=80000
开始下载任务
p =10003
Length =52728
可以看到现在开始下载任务之前就可以执行其他的任务了。最大条件的利用了资源。
Task.Delay方法创建一个Task对象,该对象暂停其在线程中的处理。
与Thread.Sleep()阻塞线程不同的是,Task.Delay不会阻塞线程,线程可以继续处理其它的工作。
static void Main(string[] args)
{
Task<int> value = FindSeriesSum(100000);
Debug.WriteLine("主线其他任务开始");
CountBig(10000);
CountBig(10001);
CountBig(10002);
Thread.Sleep(1000);
CountBig(10003);
Debug.WriteLine("Length =" + value.Result);
Console.ReadKey();
}
public static async Task<int> FindSeriesSum(int i1)
{
await Task.Delay(1000);
WebClient wc = new WebClient();
Debug.WriteLine("开始下载任务");
string str =await wc.DownloadStringTaskAsync("https://github.com/");
return str.Length;
}
private static void CountBig(int p)
{
for (int i = 0; i < p; i++)
{
if (i == p - 1)
Debug.WriteLine("p =" + p);
}
}
主线其他任务开始
p =10000
p =10001
p =10002
开始下载任务
p =10003
Length =52728