Niko
Niko

Reputation: 832

Asynchronous database operations in non-static method

I have a database represented by EntityFramework and I am adding an elements to it in async Task. My method is in simplification like that:

    private async Task SavePoint(Point point)
    {
        using (var ctx = new testDBEntities())
        {
            ctx.Points.Add(point);
            await ctx.SaveChangesAsync();
        }
    }

However the Task is non-static and I am using it simply calling SavePoint(point); (without await), since I do not need to wait for the task complete. What I want is to save a point in background, and allow the user to continue his work, and do nothing when it's added.

However I wonder if using a database context in a few tasks (when user fast adds a few points) will not provoke a race condition in database deadlock? Does it ensure a Mutal Exclusion?

Upvotes: 0

Views: 915

Answers (3)

Stephen Cleary
Stephen Cleary

Reputation: 457302

I am using it simply calling SavePoint(point); (without await), since I do not need to wait for the task complete.

Are you sure? You don't want to even know if the save failed?

You're probably better off putting the request in a try and at least notifying the user if their changes aren't being saved.

However I wonder if using a database context in a few tasks (when user fast adds a few points) will not provoke a race condition in database deadlock?

It won't cause a deadlock, and in this particular case, there is no possibility of a race condition. This is because each of your database updates is just an INSERT.

See here for the more general case of handling concurrency concerns in EF.

Upvotes: 4

Andrii Litvinov
Andrii Litvinov

Reputation: 13192

You are mixing different concerns together.

What I want is to save a point in background, and allow the user to continue his work, and do nothing when it's added.

You can mark your event handler (I assume you execute your logic from event handler) async and then await your DB access operation. Marking handler async will make sure that UI won't be blocked during DB operation and user will be able to continue interacting with UI.

However I wonder if using a database context in a few tasks (when user fast adds a few points) will not provoke a race condition in database deadlock? Does it ensure a Mutal Exclusion?

No matter whether you use await or not UI will not block and user will be able to initiate another operation that might cause a deadlock.

It is better to await your DB operation because it gives you possibility catch the exception and either retry or notify the user that something went wrong. If you don't await you will loose information about exception and application state will be inconsistent.

Just to reiterate, no matter whether you use await or not, the UI won't be blocked if that's your concern.

Upvotes: 0

Eldho
Eldho

Reputation: 8301

Calling SavePoint(point) without awaiting it causes a "Because this call is not awaited, the current method continues to run before the call is completed" warning in visual studio. On the page for that warning it states:

Consider this scenarios.

  • The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete.

  • Calling method depend on the results of the call or, minimally, the called method is expected to complete before you return from the method that contains the call

  • what happens with exceptions that are raised in the called async method. An exception that’s raised in a method that returns a Task or Task is stored in the returned task. If you don't await the task or explicitly check for exceptions, the exception is lost.

In your scenario you can move like this, it will work to execute asynchronously

Task.Run(() => SavePoint(point));

Upvotes: 0

Related Questions