Simplify Asynchronous Calls in .NET
Since .Net 4.5, the async/await pattern has been a great tool to simplify asynchronous calls. However, in WPF I frequently need to make async calls from a non-async function or event. Often, this happens because I’m overriding a virtual function in an inherited class of a framework that I’m using and that function is synchronous. To help with this, I created an async helper class:
static class AsyncHelper { public static void ExecutAsyncAsTask<T>(Task<T> task, Action<T> finished, Action<Exception> error) { Task.Factory.StartNew(() => { try { task.Wait(); if (task.Exception != null) { App.Current.Dispatcher.Invoke(new Action(() => { error(task.Exception); })); } else { App.Current.Dispatcher.Invoke(new Action(() => { finished(task.Result); })); } } catch (Exception ex) { App.Current.Dispatcher.Invoke(new Action(() => { error(ex); })); } }); } public static void ExecutAsyncAsTask(Task task, Action finished, Action<Exception> error) { Task.Factory.StartNew(() => { try { task.Wait(); if (task.Exception != null) { App.Current.Dispatcher.Invoke(new Action(() => { error(task.Exception); })); } else { App.Current.Dispatcher.Invoke(new Action(() => { finished(); })); } } catch (Exception ex) { App.Current.Dispatcher.Invoke(new Action(() => { error(ex); })); } }); }This class takes the async method as the 1st param, and success and error functions as the 2nd and 3rd. An example of calling the function might be:
fileNames) { if (!CheckIsValid()) return; IsBusy = true; AsyncHelper.ExecutAsyncAsTask(UploadFiles(fileNames), () => { IsBusy = false; _toasterService.Info("Files Added To Queue", fileNames.Length.ToString() + " file added to upload queue!"); }, x => { IsBusy = false; _toasterService.Error("Queue Error", "Error Queuing Files"); }); } private async Task UploadFiles(string[] fileNames) { var vms = fileNames.Select(i => FileToViewModel(i)); await _trackerService.PostMediaUpload(SelectedOffice.Id, vms); }This is a nice little helper to get around situations where you need to call async functions from a synchronous function. Enjoy!