/// <summary> /// Example of using async/await to add threading (non-blocking) to our app. /// /// Can you see how these are basically doing the same thing? /// </summary> private async Task DoWorkWithAsync() { txtLog.Clear(); var watch = new Stopwatch(); watch.Start(); // let user know we're working... statusLabel.Text = "Processing payment..."; // call slow API var chargeResults = await Task.Run(() => SlowApiCall.ProcessPayment()); // update UI with results txtLog.AppendText($"Process Payment Results: {chargeResults}{Environment.NewLine}"); // let user know we're saving to the database statusLabel.Text = "Saving to database..."; // call database with results from API var dbResults = await Task.Run(() => SlowDatabase.LogCharge(chargeResults)); // update UI with results txtLog.AppendText($"Database Results: {dbResults}{Environment.NewLine}"); statusLabel.Text = "DONE!"; txtLog.AppendText($"Done!{Environment.NewLine}{Environment.NewLine}"); watch.Stop(); txtTotalTime.Text = watch.Elapsed.ToString(); }
/// <summary> /// This call will block the UI thread... it also shows off the C# yield statement /// </summary> private void btnDoWorkNormal_Click(object sender, EventArgs e) { txtLog.Clear(); var watch = new Stopwatch(); watch.Start(); // let user know we're working... statusLabel.Text = "Processing payment..."; // call slow API var chargeResults = SlowApiCall.ProcessPayment(); // update UI with results txtLog.AppendText($"Process Payment Results: {chargeResults}{Environment.NewLine}"); statusLabel.Text = "Saving to database..."; // call database with results from API var dbResults = SlowDatabase.LogCharge(chargeResults); // update UI txtLog.AppendText($"Database Results: {dbResults}{Environment.NewLine}"); statusLabel.Text = "DONE!"; txtLog.AppendText($"Done!{Environment.NewLine}{Environment.NewLine}"); watch.Stop(); txtTotalTime.Text = watch.Elapsed.ToString(); }
private void btnNonBlockedUIManual_Click(object sender, EventArgs e) { txtLog.Clear(); var watch = new Stopwatch(); watch.Start(); // let user know we're working... statusLabel.Text = "Processing payment..."; // call slow API Task.Run(() => SlowApiCall.ProcessPayment()) .ContinueWith(prevTask => { var chargeResults = prevTask.Result; AsyncHelper.BeginOnUIThread(() => { // update UI with results txtLog.AppendText($"Process Payment Results: {chargeResults}{Environment.NewLine}"); // let user know we're working statusLabel.Text = "Saving to database..."; }); // call database with results from API return(SlowDatabase.LogCharge(chargeResults)); }).ContinueWith(prevTask => { // call database with results from API var dbResults = prevTask.Result; AsyncHelper.BeginOnUIThread(() => { // update UI txtLog.AppendText($"Database Results: {dbResults}{Environment.NewLine}"); statusLabel.Text = "DONE!"; txtLog.AppendText($"Done!{Environment.NewLine}{Environment.NewLine}"); watch.Stop(); txtTotalTime.Text = watch.Elapsed.ToString(); }); }); }
/// <summary> /// Example of using continuations (with coroutines) to add threading (non-blocking) to our app. /// /// Still using yield return, but our caller doesn't just enumerate the results /// because we don't want to block the UI. However, we're not having to use callbacks here. /// /// Why not? /// /// See AsyncResult code + the calling code. This ideas was popularized in .NET by the Caliburn /// library (which Deployer uses). /// </summary> private IEnumerable <IResult> DoWorkWithManualContinuations() { txtLog.Clear(); var watch = new Stopwatch(); watch.Start(); // let user know we're working... statusLabel.Text = "Processing payment..."; string chargeResults = null; // call slow API yield return(new AsyncResult <string>( action: SlowApiCall.ProcessPayment, callback: x => chargeResults = x, errorCallback: ex => MessageBox.Show(ex.ToString()))); // update UI with results txtLog.AppendText($"Process Payment Results: {chargeResults}{Environment.NewLine}"); // let user know we're working... statusLabel.Text = "Saving to database..."; string dbResults = null; // call database with results from API yield return(new AsyncResult <string>( action: () => SlowDatabase.LogCharge(chargeResults), callback: x => dbResults = x, errorCallback: ex => MessageBox.Show(ex.ToString()))); // update UI txtLog.AppendText($"Database Results: {dbResults}{Environment.NewLine}"); statusLabel.Text = "DONE!"; txtLog.AppendText($"Done!{Environment.NewLine}{Environment.NewLine}"); watch.Stop(); txtTotalTime.Text = watch.Elapsed.ToString(); }