Return to async task completion

I am working on an ASP.NET MVC 4 web application. I am using .NET 4.5 and trying to use the new asynchronous APIs.

I have a couple of situations where I want to schedule the launch of async Task later, when I immediately return immediately the importance immediately. For example, here is the Login method that I want to return the new SessionID as soon as possible, but as soon as I get back to the SessionID, I want to clear the old SessionID:

public async Task<Guid> LogIn(string UserName, string Password) { //Asynchronously get ClientID from DB using UserName and Password Session NewSession = new Session() { ClientID = ClientID, TimeStamp = DateTime.Now }; DB.Sessions.Add(NewSession); await DB.SaveChangesAsync(); //NewSession.ID is autopopulated by DB CleanSessions(ClientID); //Async method which I want to execute later return NewSession.ID; } private async void CleanSessions(int ClientID) { //Asynchronously get expired sessions from DB based on ClientID and mark them for removal await DB.SaveChangesAsync(); } 

I tried a bunch of different things, including combinations of Task.Run () and Parallel.Invoke (), but CleanSessions is never called. How to achieve planning of background tasks?

+7
source share
2 answers

Running tasks in ASP.NET without a request is not recommended. This is dangerous.

In doing so, change CleanSessions to return Task , and you can do it like this:

 Task.Run(() => CleanSessions()); 

In your case, I think that everything will be fine, because there is no long-term problem if CleanSessions fails or does not end in the middle of execution (which can happen in ASP.NET due to recycling). If you want to notify ASP.NET that you have some kind of work that is not related to the request, you can use the BackgroundTaskManager from my blog like this:

 BackgroundTaskManager.Run(() => CleanSessions()); 
+13
source

If, as already noted, you are trying to do something "fire and forget", but inside ASP.NET, then you may need to look at ConfigureAwait ; you can use this as part of await to tell it to ignore the synchronous context. The synchronization context associates it with the ASP.NET runtime pipeline, but if this is not necessary, you can avoid it. For example:

 public async Task<Guid> LogIn(string UserName, string Password) { //Asynchronously get ClientID from DB using UserName and Password Session NewSession = new Session() { ClientID = ClientID, TimeStamp = DateTime.Now }; DB.Sessions.Add(NewSession); await DB.SaveChangesAsync().ConfigureAwait(false); //NewSession.ID is autopopulated by DB await CleanSessions(ClientID).ConfigureAwait(false); //Async method which I want to execute later return NewSession.ID; } // simplified: no need for this to be full "async" private Task CleanSessions(int ClientID) { //Asynchronously get expired sessions from DB based on ClientID return DB.SaveChangesAsync(); } 
0
source

All Articles