Skip to content

Instantly share code, notes, and snippets.

@bretkoppel
Created March 3, 2014 19:38
Show Gist options
  • Save bretkoppel/9332983 to your computer and use it in GitHub Desktop.
Save bretkoppel/9332983 to your computer and use it in GitHub Desktop.
AsyncFormsDemo
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AsyncPresoForms
{
public partial class Form1 : Form
{
private const string googleUrl = @"http://cnn.com/";
private const string ddgUrl = @"https://duckduckgo.com";
private readonly WebClient _client = new TimeoutWebClient();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.ResetText();
// download two files serially - blocks the UI
var result = _client.DownloadString(googleUrl).Substring(0, 100) + Environment.NewLine;
result += _client.DownloadString(ddgUrl).Substring(0, 100);
textBox1.Text = result;
}
private void button2_Click(object sender, EventArgs e)
{
textBox1.ResetText();
// download two files serially using event/callback idiom
// UI remains responsive
var client2 = new WebClient();
_client.DownloadStringCompleted += (o, args) =>
{
textBox1.Text = args.Result.Substring(0, 100);
// what is this, javascript?
client2.DownloadStringCompleted += (io, iargs) => textBox1.Text += args.Result.Substring(0, 100);
client2.DownloadStringAsync(new Uri(ddgUrl));
};
// trigger the downloads
_client.DownloadStringAsync(new Uri(googleUrl));
}
private void button3_Click(object sender, EventArgs e)
{
textBox1.ResetText();
// download two files serially using TPL
// UI remains responsive
var googleTask = Task.Run(() => _client.DownloadString(googleUrl));
var ddgTask = googleTask.ContinueWith((t) =>
{
return t.Result.Substring(0, 100) + Environment.NewLine + _client.DownloadString(ddgUrl).Substring(0, 100);
});
// could do more .ContinueWith here without deep nesting...
textBox1.Text = ddgTask.Result;
}
private void button4_Click_1(object sender, EventArgs e)
{
textBox1.ResetText();
// download two files in parallel using TPL
var client2 = new WebClient();
var googleTask = Task.Run(() => _client.DownloadString(googleUrl));
var ddgTask = Task.Run(() => client2.DownloadString(ddgUrl));
var completionTask = Task.WhenAll(new[] {googleTask, ddgTask});
// blocks the UI
completionTask.Wait();
textBox1.Text = googleTask.Result.Substring(0, 100) + Environment.NewLine + ddgTask.Result.Substring(100);
}
// note: this is the only time it is appropriate to use async void... more on that later!
private async void button5_Click(object sender, EventArgs e)
{
textBox1.ResetText();
// download two files in parallel using await
var client2 = new WebClient();
var googleTask = _client.DownloadStringTaskAsync(googleUrl);
var ddgTask = client2.DownloadStringTaskAsync(ddgUrl);
// no blocked UI!
await Task.WhenAll(new[] { googleTask, ddgTask });
textBox1.Text = googleTask.Result.Substring(0, 100) + Environment.NewLine + ddgTask.Result.Substring(100);
}
private void button6_Click(object sender, EventArgs e)
{
textBox1.ResetText();
var task = Deadlock(true);
// deadlocks!
task.Wait();
textBox1.Text = task.Result;
}
private void button7_Click(object sender, EventArgs e)
{
textBox1.ResetText();
var task = Deadlock(false);
// no deadlock!
task.Wait();
textBox1.Text = task.Result;
}
private async Task<string> Deadlock(bool makeDeadlock)
{
if (makeDeadlock)
await Task.Delay(1000);
else
await Task.Delay(1000).ConfigureAwait(false);
return "Finished!";
}
private async void button8_Click(object sender, EventArgs e)
{
textBox1.ResetText();
// the right way(note that false works here as well)
textBox1.Text = await Deadlock(true);
}
private class TimeoutWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
var req = base.GetWebRequest(address);
req.Timeout = 3000;
return req;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment