When using AsParallel().ForAll
, and when to use async await
?
I'm providing an example with a download routine and a file manipulation routine.
AsParallel().ForAll
performs better in parallel download operation.
async await
performs best in parallel file manipulation operation.
If anyone can explain the difference and the best use scenario for each, I thank you.
Code (also available in .NET Fiddle ):
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Parallel
{
public enum Actions
{
TestParallelDownload,
TestParallelSaveFile,
TestAsyncDownload,
TestAsyncSaveFile
}
public class Program
{
public static async Task Main(string[] args)
{
try
{
var stopWatch = Stopwatch.StartNew();
var itemAmount = 5;
await Test(Actions.TestParallelDownload, itemAmount);
await Test(Actions.TestParallelSaveFile, itemAmount);
await Test(Actions.TestAsyncDownload, itemAmount);
await Test(Actions.TestAsyncSaveFile, itemAmount);
stopWatch.Stop();
Console.WriteLine("Finish {0}", stopWatch.Elapsed);
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Err", ex.Message);
Console.ReadLine();
}
}
public static async Task Test(Actions action, int itemAmount)
{
string[] items = Enumerable.Range(0, itemAmount).Select(i => Guid.NewGuid().ToString()).ToArray();
var stopWatch = Stopwatch.StartNew();
switch (action)
{
case Actions.TestParallelDownload:
items.AsParallel().ForAll(item => DownloadAsync(item));
break;
case Actions.TestParallelSaveFile:
items.AsParallel().ForAll(item => SaveAsync(item));
break;
case Actions.TestAsyncDownload:
foreach (var item in items)
await DownloadAsync(item);
break;
case Actions.TestAsyncSaveFile:
foreach (var item in items)
await SaveAsync(item);
break;
}
stopWatch.Stop();
Console.WriteLine($"{action.ToString()} Call: Time: {stopWatch.Elapsed}");
}
public static async Task SaveAsync(string textToWrite)
{
string filePath = @"C:\temp\file2.txt";
byte[] encodedText = Encoding.Unicode.GetBytes(textToWrite);
using (var sourceStream = new FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true))
{
await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
};
}
public static async Task DownloadAsync(string name)
{
var uri = new Uri("https://images.sftcdn.net/images/t_app-logo-l,f_auto,dpr_auto/p/ce2ece60-9b32-11e6-95ab-00163ed833e7/2183169552/the-test-fun-for-friends-logo.png");
using (var client = new WebClient())
{
await client.DownloadFileTaskAsync(uri, $"{name}.png");
}
}
}
}
Unfortunately, because it contains file manipulation, the code does not run correctly in cloud , you need to create a .NET Core Console project to run it.