adams
adams

Reputation: 177

Add some extra work to SaveChangesAsync

I have to add some extra work to a database context SaveChanges method. I need this work to be done after base.SaveChanges() method, because I need records Ids after they were added to the database. The outline of my SaveChanges methods looks like follows (two try..catch blocks are needed to isolate saving db changes from other operations):

public override int SaveChanges()
{
    using (var scope = new TransactionScope())
    {
        var result = 0;
        try
        {
            result = base.SaveChanges();
        }
        catch (Exception ex)
        {
            //Log context exception             
            throw;
        }

        try
        {
            //do some extra work
            var extraWorkRes = DoExtraWork();
        }
        catch (Exception ex)
        {
            //Log exception
            throw;
        }

        scope.Complete();
        return result;
    }
}

My problem is SaveChangesAsync method, because I don't have a lot of experience with .NET tasks and don't know if I am overriding it correctly.

public override  async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
 {
     using (var scope = new TransactionScope())
     {
         var result = 0;

         try
         {
             result = await base.SaveChangesAsync(cancellationToken);
         }
         catch (Exception ex)
         {
             //log context exception
             throw;
         }

         try
         {
            //do some extra work
            var extraWorkRes = await DoExtraWorkAsync(cancellationToken);
         }
         catch (Exception ex)
         {
             //Log exception
             throw;
         }

         scope.Complete();
         return result;
     }
 }

 private Task<int> DoExtraWorkAsync(CancellationToken cancellationToken)
 {
    return Task.Run<int>(() => this.DoExtraWork(cancellationToken));
 }

I need help, some advice how to correctly override SaveChangesAsync.

Thanks in advance for your help.

Upvotes: 0

Views: 1685

Answers (1)

Steve Lillis
Steve Lillis

Reputation: 3256

Wrapping a synchronous method in a Task.Run and calling it TheOriginalMethodAsync is a common code smell.

Is DoExtraWork() a CPU bound operation that you'd like to free the current thread while its happening? If so, refactor it to be inline:

var extraWorkRes = await Task.Run<int>(() => this.DoExtraWork());

If not, simply call it directly:

var extraWorkRes = this.DoExtraWork();

Do you need the result of DoExtraWork outside of SaveChanges? If not, you don't need to assign it.

In case this is your real code, please also note that you missed a closing bracket from Task.Run. Everything else looks fine to me. Does it encounter any issues when you run it or are you just checking for sanity's sake?

Upvotes: 2

Related Questions