F#:
open System
open System.IO
open System.Net
let getHtml url printStrategy =
async { let request = WebRequest.Create(Uri url)
use! response = request.AsyncGetResponse()
use stream = response.GetResponseStream()
use reader = new StreamReader(stream)
let contents = reader.ReadToEnd()
do printStrategy url contents
return contents }
let sites = ["http://www.bing.com";
"http://www.google.com";
"http://www.yahoo.com";
"http://msdn.microsoft.com/en-us/fsharp/default.aspx"]
let printStrategy url (contents:string) =
printfn "%s - HTML Length %d" url contents.Length
let sitesHtml = Async.Parallel [for site in sites -> getHtml site printStrategy]
|> Async.RunSynchronously
do printfn "\r\nProcess Complete\r\nPress any key to continue"
do Console.ReadLine() |> ignore
C#:
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Linq;
namespace CSharpAsync
{
class Program
{
static async Task<string> GetHtml(string url,
Action<string, string> printStrategy)
{
var request = WebRequest.Create(new Uri(url));
using (var response = await request.GetResponseAsync())
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
var contents = reader.ReadToEnd();
printStrategy.Invoke(url, contents);
return contents;
}
}
}
}
static async Task ProcessSites(string[] sites,
Action<string, string> printStrategy)
{
var sitesHtml =
await TaskEx.WhenAll(
sites.Select(site => GetHtml(site, printStrategy)));
Console.WriteLine("\r\nProcess Complete\r\nPress any key to continue");
}
static void Main(string[] args)
{
var sites = new[] { "http://www.bing.com",
"http://www.google.com",
"http://www.yahoo.com",
"http://msdn.microsoft.com/en-us/fsharp/default.aspx" };
Action<string, string> printStrategy =
(url, contents) =>
Console.WriteLine("{0} - HTML Length {1}", url, contents.Length);
ProcessSites(sites, printStrategy).Wait();
Console.ReadLine();
}
}
}
VB:
Imports System
Imports System.IO
Imports System.Net
Imports System.Threading.Tasks
Imports System.Linq
Module Module1
Async Function GetHtml(ByVal url As String, ByVal printStrategy As Action(Of String, String)) As Task(Of String)
Dim request = WebRequest.Create(New Uri(url))
Using response = Await request.GetResponseAsync()
Using stream = response.GetResponseStream()
Using reader = New StreamReader(stream)
Dim contents = reader.ReadToEnd()
printStrategy.Invoke(url, contents)
Return contents
End Using
End Using
End Using
End Function
Async Function ProcessSites(ByVal sites As String(), ByVal printStrategy As Action(Of String, String)) As Task
Dim sitesHtml = _
Await TaskEx.WhenAll(sites.Select(Function(site) GetHtml(site, printStrategy)))
Console.WriteLine("{0}Process Complete{0}Press any key to continue", _
Environment.NewLine)
End Function
Sub Main()
Dim sites = New String() {"http://www.bing.com", _
"http://www.google.com", _
"http://www.yahoo.com", _
"http://msdn.microsoft.com/en-us/fsharp/default.aspx"}
Dim printStrategy As Action(Of String, String) = _
Sub(url, contents) Console.WriteLine("{0} - HTML Length {1}", url, contents.Length)
ProcessSites(sites, printStrategy).Wait()
Console.ReadLine()
End Sub
End Module
Hey thanks for the code-snippets, it shows a nice side-by-side comparison of the different languages.
ReplyDeleteThough your C# could be cleaner if you didn't use nested using blocks (i.e. remove braces from the top two using statements). Also I'm not sure why you created an extra method for 'ProcessSites()' instead of having it in-line like the F# version?
Also I might be mistaken but I think you have an extra Wait on 'ProcessSites(sites, printStrategy).Wait();' as it looks like 'var sitesHtml = await TaskEx.WhenAll' already accomplishes this?
- Demis
Thanks for your comments. You make a good point about the removal of the unnecessary braces from the top two using statements. The addition of the braces is an old habit of mine that stems from the coding standards of a company for which I use to work. I should definitely retire that habit.
ReplyDeleteTomas's post (http://tomasp.net/blog/csharp-fsharp-async-intro.aspx) goes into detail about the reasons for the extra method and the extra Wait call.
Hey thanks for the code-snippets, it shows a nice side-by-side comparison of the different languages.
ReplyDeleteThough your C# could be cleaner if you didn't use nested using blocks (i.e. remove braces from the top two using statements). Also I'm not sure why you created an extra method for 'ProcessSites()' instead of having it in-line like the F# version?
Also I might be mistaken but I think you have an extra Wait on 'ProcessSites(sites, printStrategy).Wait();' as it looks like 'var sitesHtml = await TaskEx.WhenAll' already accomplishes this?
- Demis