12

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 ??

3
  • Do you want to update other records with Depth==1 or just the first record? Commented May 22, 2015 at 5:21
  • @MehrdadKamelzadeh:other records too not just depth==1 and id==1.others records too because at each refresh i would be passing different id to my controller Commented May 22, 2015 at 5:23
  • So why you have written where(x=>x.Depth==1).FirstorDefualt() ?? it returns only the first record found by the criteria. I mean it finds all the records which their Depth==1 and then it returns just the first one! Commented May 22, 2015 at 5:24

2 Answers 2

15

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();
            }
        }
Sign up to request clarification or add additional context in comments.

8 Comments

like how as because my method is actionresult.can you please post any sample?
See my updated answer. You need to return the action result as you normally would such a view or redirect.
Please see my updated question and i have dont with what you have written but getting thsi error:HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete
Before getting into the the async world (all involved methods must be async up the chain), so revert your code to synchronous: remove async Task<> from the method, and await, call the synchronous context.SaveChanges method instead. I mentioned in my previous comment a possible error in your code where "data" is not being used. Once this issue is solved, you can try async calls.
Unfortunately, you cannot call an async method from @Html.Action() - it's not supported: aspnetwebstack.codeplex.com/workitem/601 - I would consider creating a helper class to increment the counter, and calling it from the action that loads the view from which you're using @Html.Action().
|
9

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.

15 Comments

Please see my updated question and i have dont with what you have written but getting thsi error:HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete
HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete
Also what version of ASP are you using?
Have a look at this post for the various alternatives when doing asynchronous calls with MVC codeclimber.net.nz/archive/2012/01/09/…
The one that says async child actions are not supported? This is true, but If your controller is an AsyncController there should be a way to make the action asynchronous as indicated in the link to that blog post i posted
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.