Reputation: 1
I am working on an asp.net mvc5 web application + Entity Framework 6. and I want to have a repository model class inside my application. currently I am following this approach to have async action methods and async repository model class.
for example I have the following repository save method:
public class Repository
{
private Entities t = newEntities();
public async Task Save()
{
await t.SaveChangesAsync();
}
which I am calling from my action methods as follow:
Repository repository = new Repository();
public async Task<ActionResult> GetResourceByName(string resourcename)
{
await repository.Save();
}
so is this a correct approach? as I am doing the following:
I define the repository method as a Task & also the Action method as Task. so should I have both of them as Task(s).?
I am using await
twice on the action method (when calling the repo method) and on the repository? so are these await
redundant?
//please note that this is only a simple example of a repository method which is just used to save model,, but I am asking about the approach itself as I will be using this approach in a more complex repository methods ..
Upvotes: 1
Views: 1356
Reputation: 8979
To answer your questions:
await
make sense. No, they are not redundant.To understand why you might (not necessary) need to await
twice, I suggest you take a look at this article which gives a pretty clear example of how and why it works:
C# async and await: Why Do We Need Them?
If you want to use repositories and may want to consider using services for you business logic, I would recommend you check this project that is easily extensible and generic:
URF - Unit of Work & Repositories Framework
Before you consider developing everything from scratch, you should check it out. I really love this project!
Upvotes: 0
Reputation: 14856
Regardless of the other answers, here is why you should use await
and more.
ASP.NET has a synchronization context that will be captured on each await
and the continuation (the rest of the async
method) will be posted for that context. That means not only thread switching but populating the switched to thread with the ASP.NET context.
If you suffix your asynchronous calls (those with await
with a call to ConfigureAwait(false)
the ASP.NET context switching won't happen (although the thread switching will).
Because the action view engine most probably need the ASP.NET context, you can't use ConfigureAwait(false)
on the MVC action method. But you should use on all methods called by it.
So, your code should be something like this:
public class Repository
{
private Entities t = new Entities();
public async Task SaveAsync()
{
await t.SaveChangesAsync().ConfigureAwait(false);
}
}
Repository repository = new Repository();
public async Task<ActionResult> GetResourceByName(string resourcename)
{
await repository.SaveAsync();
}
Because you might not have an ASP.NET context after an await
with a call to ConfigureAwait(false)
you should pass as arguments everything you need from the ASP.NET context.
Upvotes: 1
Reputation: 12420
Contrary to both answers two awaits
are not necessary. await
and async
are only necessary if you need the result from a Task
before continuing. If you don't need that result then you don't need to mark your method async
.
This means this method...
public async Task Save()
{
await t.SaveChangesAsync();
}
Can be simplified into
public Task Save()
{
return t.SaveChangesAsync();
}
Even though these are functionally the same, I like the second version because it shows recognition that Task
is the asynchronous work and async/await are only signals to the compiler to wait for that work to complete.
Upvotes: 2
Reputation: 5705
Basically: Once you go async/await, all the call chain should be async/await to avoid thread related issues...
If you don't await then that is called: "Fire and Forget" which is not recommended, because then this request will be returned to the user with success message, but at a later time, the call that you made without the await could fail and throw an exception and you wont have any idea of what is that exception...
Upvotes: 2