Print Page | Close Window

VS 2012 Async

Printed From: IdeaBlade
Category: Cocktail
Forum Name: Community Forum
Forum Discription: A professional application framework using Caliburn.Micro and DevForce
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3639
Printed Date: 25-Mar-2025 at 10:11pm


Topic: VS 2012 Async
Posted By: smi-mark
Subject: VS 2012 Async
Date Posted: 20-Sep-2012 at 8:53am
Just curious as to what the best practices are now for writing async code.

Previously we have had code such as:


  Busy.AddWatch();
                Repository.SaveAsync(() =>
                                         {
                                           Success Logic Here
                                         }, ErrorHandler.HandleError)
                    .WhenCompleted(e => Busy.RemoveWatch());


Now we have code like


                Busy.AddWatch();
                var op =  Repository.SaveAsync().ContinueWith(t => Busy.RemoveWatch());
                op.HandleError(ErrorHandler.HandleError);
                await op;
                Success Logic Here


Is this the best way? I have seen people wrapping try handlers around await calls but that seems messy.

I see that HandleError doesn't return a Task so you can't await it. Is that by design?



Replies:
Posted By: mgood
Date Posted: 20-Sep-2012 at 9:42am
With async/await you write code very much like you would write synchronous code. Error handling is done using try/catch. The following is an example. In this case I'm just rethrowing the exception and handle it in the UnhandledException handler.

        public async void Delete()
        {
            await _dialogManager.ShowMessageAsync(
                string.Format("Are you sure you want to delete {0}?", ActiveStaffingResource.FullName),
                DialogResult.Yes, DialogResult.No, DialogButtons.YesNo);

            try
            {
                using (ActiveDetail.Busy.GetTicket())
                {
                    ActiveUnitOfWork.StaffingResources.Delete(ActiveStaffingResource);
                    await ActiveUnitOfWork.CommitAsync();
                }

                ActiveItem.TryClose();
            }
            catch (TaskCanceledException)
            {
                ActiveUnitOfWork.Rollback();
            }
            catch (Exception)
            {
                ActiveUnitOfWork.Rollback();
                throw;
            }
        }


Posted By: mgood
Date Posted: 20-Sep-2012 at 9:46am
Also, here is a useful error handler that I'm using in TempHire v2. 

    public class ErrorHandler : IErrorHandler
    {
        private readonly IDialogManager _dialogManager;

        [ImportingConstructor]
        public ErrorHandler(IDialogManager dialogManager)
        {
            _dialogManager = dialogManager;
        }

        #region IErrorHandler Members

        public void HandleError(Exception ex)
        {
            string customMessage = null;
            if (ex is EntityManagerSaveException &&
                ((EntityManagerSaveException) ex).FailureType == PersistenceFailure.Concurrency)
                customMessage = "Another user has previously saved the current record.";

            if (ex is TaskCanceledException)
            {
                // Log and ignore
                LogFns.DebugWriteLine(ex.Message);
                return;
            }

            _dialogManager.ShowMessageAsync(customMessage ?? ex.Message, DialogButtons.Ok);
        }

        #endregion
    }


Posted By: smi-mark
Date Posted: 21-Sep-2012 at 6:19am
That works great, thanks. This really helps clean up and simplify the code!



Print Page | Close Window