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();
}
}
}