Created
March 3, 2014 19:38
-
-
Save bretkoppel/9332983 to your computer and use it in GitHub Desktop.
AsyncFormsDemo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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