HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

C# Async and DataContext access

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
asyncanddatacontextaccess

Problem

I'm using a DataContext to insert an object. Currently it's working, but I'm feeling things could be done better. Method is called from UI (Using Caliburn Micro Binding). IsBusy is a property used by the UI (Xceed Extended WPF Toolkit) to display a wait message.

Repository inherits from DataContext (using Entity Code First).

public async void AddTemplate()
{
    IsBusy = true;

    await Task.Run(() => {
        using (var repo = new Repository())
        {
            var template = new Template() { ... };
            try
            {
                repo.Templates.Add(template);
                repo.SaveChanges();
                this.TryClose(true);
            }
            catch (SqlException ex)
            {
                _util.Log.AddException(Exceptions.DB_EXC, ex.Message);
            }
            catch (EntityException ex)
            {
                _util.Log.AddException(Exceptions.EF_EXC, ex.Message);
            }
            catch (Exception ex)
            {
                _util.Log.AddException(Exceptions.US_EXC, ex.Message);
            }
            finally
            {
                IsBusy = false;
            }
        }
        this.TryClose(false);
    });
}


I'm feeling odd about covering using with the await Task.Run since I can also await for repo.SaveChangesAsync(), but then IsBusy will not change (and the Wait message will not be made visible).

Solution

You should be able to await the repo.SaveChangesAsync() method.

public async Task AddTemplateAsync()
{
    var template = new Template {...};

    using (var repo = new Repository())
    {
        try
        {
            IsBusy = true;
            repo.Templates.Add(template);
            await repo.SaveChangesAsync();
        }
        catch {...}
        finally
        {
            IsBusy = false;
            TryClose();
        }
    }
}


Since AddTemplate() is an async method, it should be called AddTemplateAsync() and return a Task. Take a look at these best practices for more details. You might want to consider passing in a CancellationToken depending on your requirements.

I would also advise against swallowing the base Exception type for reasons explained here.

Code Snippets

public async Task AddTemplateAsync()
{
    var template = new Template {...};

    using (var repo = new Repository())
    {
        try
        {
            IsBusy = true;
            repo.Templates.Add(template);
            await repo.SaveChangesAsync();
        }
        catch {...}
        finally
        {
            IsBusy = false;
            TryClose();
        }
    }
}

Context

StackExchange Code Review Q#87955, answer score: 4

Revisions (0)

No revisions yet.