Use VS2017 C# 7.0 to accelerate async code

Reference: 

http://www.debug.is/2015/04/17/c-sharp-vs-go/

http://www.jb51.net/article/108159.htm


Before VS2017 C# 7:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Net;


namespace newfeature
{
    public class CacheContext
    {
        public static async Task<List<DownloadResult>> DownloadUrlsAsync(string path)
        {
            var results = new List<DownloadResult>();
            List<Task<DownloadResult>> tasks = File.ReadLines(path).Select(a =>
            DownloadAsync(a)).ToList();
            while (tasks.Any())
            {
                Task<DownloadResult> task = await Task.WhenAny(tasks);
                tasks.Remove(task);
                results.Add(task.Result);
            }
            return results;
        }


        private static async Task<DownloadResult> DownloadAsync(string url)
        {
            try
            {
                //using (System.Net.WebClient client = new WebClient())
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    // byte[] data = await client.DownloadDataTaskAsync(new Uri(url));
                    byte[] data = new byte[10];
                    await Task.Delay(5000);
                    stopwatch.Stop();
                    return new DownloadResult()
                    {
                        Url = url,
                        Time = stopwatch.ElapsedMilliseconds,
                        Success = true,
                        SizeInBytes = data.Length
                    };
                }
            }
            catch (Exception x)
            {
                Console.WriteLine("error downloading {0}: {1}", url, x);
                return new DownloadResult()
                {
                    Url = url,
                    Time = int.MaxValue,
                    SizeInBytes = 0,
                    Success = false
                };
            }
        }
    }
    public class DownloadResult
    {
        public string Url { get; set; }
        public long Time { get; set; }
        public bool Success { get; set; }
        public int SizeInBytes { get; set; }
    }
    class Program
    {


        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            List<DownloadResult> result = null;
            Action act = async () =>
            {
                result = await CacheContext.DownloadUrlsAsync(args[0]);
                if (result != null)
                {
                    foreach (DownloadResult r in result)
                    {
                        Console.WriteLine(r.Time + " " + r.Url);
                    }


                }


                result = await CacheContext.DownloadUrlsAsync(args[0]);
                if (result != null)
                {
                    foreach (DownloadResult r in result)
                    {
                        Console.WriteLine(r.Time + " " + r.Url);
                    }


                }
            };
            act();


            Console.Read();
        }
    }
}


After VS2017 C# 7.0:


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Net;


namespace newfeature
{
    public class CacheContext
    {
        private static Dictionary<string, DownloadResult> cache = new Dictionary<string, DownloadResult>();


        public static async Task<List<DownloadResult>> DownloadUrlsAsync(string path)
        {
            var results = new List<DownloadResult>();
            List<Task<DownloadResult>> tasks = File.ReadLines(path).Select(a =>
            CachedDownloadAsync(a).AsTask()).ToList();
            while (tasks.Any())
            {
                Task<DownloadResult> task = await Task.WhenAny(tasks);
                tasks.Remove(task);
                results.Add(task.Result);
            }
            return results;
        }


        private static ValueTask<DownloadResult> CachedDownloadAsync(string url)
        {
            lock (cache)
            {
               return cache.ContainsKey(url) ? new ValueTask<DownloadResult>(cache[url]): new ValueTask<DownloadResult> (DownloadAsync(url));
            }    
        }


        private static async Task<DownloadResult> DownloadAsync(string url)
        {
            try
            {
                //using (System.Net.WebClient client = new WebClient())
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    // byte[] data = await client.DownloadDataTaskAsync(new Uri(url));
                    byte[] data = new byte[10];
                    await Task.Delay(5000);
                    stopwatch.Stop();
                    DownloadResult result =  new DownloadResult()
                    {
                        Url = url,
                        Time = stopwatch.ElapsedMilliseconds,
                        Success = true,
                        SizeInBytes = data.Length
                    };
                    lock (cache)
                    {
                        cache[url] = result;
                    }
                    return result;
                }
            }
            catch (Exception x)
            {
                Console.WriteLine("error downloading {0}: {1}", url, x);
                return new DownloadResult()
                {
                    Url = url,
                    Time = int.MaxValue,
                    SizeInBytes = 0,
                    Success = false
                };
            }
        }
    }
    public class DownloadResult
    {
        public string Url { get; set; }
        public long Time { get; set; }
        public bool Success { get; set; }
        public int SizeInBytes { get; set; }
    }
    class Program
    {


        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            List<DownloadResult> result = null;
            Action act = async () =>
            {
                result = await CacheContext.DownloadUrlsAsync(args[0]);
                if (result != null)
                {
                    foreach (DownloadResult r in result)
                    {
                        Console.WriteLine(r.Time + " " + r.Url);
                    }


                }


                result = await CacheContext.DownloadUrlsAsync(args[0]);
                if (result != null)
                {
                    foreach (DownloadResult r in result)
                    {
                        Console.WriteLine(r.Time + " " + r.Url);
                    }


                }
            };
            act();


            Console.Read();
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值