.net中Task.Yield和Task.Delay说明

书上看到一个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
posted @ 2018-04-05 18:25  huey-chan  阅读(519)  评论(0编辑  收藏  举报