Simplify Asynchronous Calls in .NET Reply

misc3_bgSince .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!

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s