Reputation: 6868
This is my Table:Statistics
Id,Depth,RefreshCounter
Sample Records:
Id Depth RefreshCounter
1 1 1
2 1 0
3 1 0
4 1 0
Now what i need to do is whenever i am refreshing the page i need to increment this refreshcounter value by 1 in Database table with Depth 1.
I am calling this method like this on load of my view page:
@Html.Action("IncrementRefreshcounter", "Statistics", new { id = 1}) //for eg:1,2,3,4
Here is my code which does this:
[ChildActionOnly]
public ActionResult IncrementRefreshcounter(int id)
{
using ( var context = new MyDBContext())
{
//at each page refresh i would be passing different id to my controller from view.for eg 1,2,3,4
var data=context.Statistics.where(x=>x.Depth==1 && r.Id==id).FirstorDefualt();
context.RefreshCounter++;//Increment here RefreshCounter.
context.SaveChangesAsync();
return PartialView("xxx")
}
}
I am calling this method when my View Loads.Problem is when i run my Application first time and calling this method it successfully updated RefreshCounter by 1 but after that whenever i refresh my page and calling this method it never updated RefreshCounter for any records with Depth=1.
In my sample Records you can see that Id 1 with Depth 1 have refresh counter with value 1 because it was the first time when i have run my application and it has successfully updated that value but after that it is never updating any value for eg:Id 2 Depth 1
It is incrementing only 1 time RefreshCounter but after that it never increments that variable.
Can anybody tell me what the problem is SaveChangesAsync ??
Upvotes: 12
Views: 28578
Reputation: 13495
Try this:
public async Task<ActionResult> IncrementRefreshcounter(int id)
{
using ( var context = new MyDBContext())
{
//at each page refresh i would be passing different id to my controller from view.for eg 1,2,3,4
var data=context.Statistics.where(x=>x.Depth==1 && r.Id==id).FirstorDefualt();
context.RefreshCounter++;//Increment here RefreshCounter.
await context.SaveChangesAsync();
}
}
SaveChanges
will execute on the current thread and block the thread while waiting for the query to complete, preventing the thread from doing other work, even though the thread is just sitting there waiting for IO.
SaveChangesAsync
will kick off the IO command and then free up the request thread to do other work while the IO is in progress. Once the IO completes, the rest of the method is executed on the captured synchronization context.
So for a web server using asyncrhonous APIs for IO bound work enables you to serve more requests with fewer threads and thus makes your application more scalable and it will use much less memory as well as each thread has 1MB of stack space by default.
Synchronous work is like the SaveChanges
method. The method call does not return until the changes are saved.
Asynchronous work is like SaveChangesAsync
, the method call initiates the operation and returns a Task
so you can keep track of it. The changes are then saved in the background some time later and in the mean time you can use the returned Task
to keep track of the operation.
Upvotes: 9
Reputation: 2241
You have to await the save otherwise the method will continue and your context would go out of scope before saving changes. You have to make the method asynchronous, too.
public **async** Task<ActionResult> IncrementRefreshcounter(int id)
{
using ( var context = new MyDBContext())
{
//at each page refresh i would be passing different id to my controller from view.for eg 1,2,3,4
var data=context.Statistics.where(x=>x.Depth==1 && r.Id==id).FirstorDefualt();
context.RefreshCounter++;//Increment here RefreshCounter.
await context.SaveChangesAsync();
}
}
Upvotes: 15