1

BACKGROUND: I'm trying to make an async Task in my MVCcontroller class that will call a method in my modelclass which will insert a bunch of data into multiple sql tables using an already existing sql table. As the frontend will time out when called from there if it's not async (It makes millions of operations) I wish to use this controller task to run async operations. Once it is done with it's operations it should write to a file that I will see and understand that all computations are done. Yes, there might be smarter ways of calling the Task but that's for later, for now I just wish to figure out how to do the async set-up.

PROBLEM/QUESTION: Controller says that the await_part can not await void, can I just return something like Json(success)? Or how do I do this set up? I'm kind of a rookie.

In the model method I wish to look at the existing sql-table and use it to create more sql-tables that I will persist in the database, not really interested in sending anything back besides something that says "I'm done with the calculations".

Controller calling the model method that will perform actions.

 public async Task GenerateBackEndCalculations(string sqlTableName)
    {
        if (nameOfTable == "sqlTableName")
        {
           await _context.BackEndCalculations();                
        }           

    }

the model method that looks like this

public void BackEndCalculations ()
    {            
        Do something here, and maybe return something if I have to???   

    }
4
  • use Task.Run(()=>BackEndCalculations()).Wait(); Commented Jul 22, 2017 at 7:13
  • Async should only return void for event handlers. In your case it should not return void. Furthermore, even if this is done async, keep in mind that the response will not return to the front end until the whole operation is completed. The front end can issue the request asyn and then do other things until the repsonse is returned from the server but you need to do that on the front end side. Commented Jul 22, 2017 at 7:19
  • 1
    Don't use Task.Run(()=>BackEndCalculations()).Wait(); Wrapping already asynchronous method with Task.Run is waste of resources(threads) and you will loose all benefits of asynchronous methods. Commented Jul 22, 2017 at 7:19
  • ............................... Commented Jul 23, 2017 at 16:40

4 Answers 4

2

If i understand you correctly, you can change void to Task (and add async keyword) any where and as long as there is a await in your function. If you don`t have any async method to await, just return some completed Task. For example Task.CompletedTask;

public async Task BackEndCalculations ()
{            
   Do something async
}

Or

public Task BackEndCalculations ()
{            
  Do something sync
  return Task.CompletedTask;
}
Sign up to request clarification or add additional context in comments.

2 Comments

No this will not do.see my comment to the OP question.
Well I'm just lost now, I'll take this thread to a colleague and show it as I don't get the flag and file thing either. Thanks for helping out even though I don't really get all of it :)
0

If you want to use await in BackEndCalculations it cannot return void, it needs to return a Task.

Here are your options:

public Task BackEndCalculations() { ... }
public Task<JsonObject> BackEndCalculations() { ... }
public async Task BackEndCalculations() { ... }
public async Task<JsonObject> BackEndCalculations() { ... }

Depending on how the body of your function looks like

6 Comments

Not this will not help. See my comment to question.
Will not work because? How is your comment in OP's question related to this solution?
Returning a Task will not help because the server will not return a response yo the client until the whole operation is completed. The OP is trying to use async to return to the client right away and thats not possible. See the answer from @stephencleary below.
As I said in the question I will write to a text file once the operations is done, not send anything back to the front end so async will help as I understand it. Thanks for answers.
@johan no it will not. That is not how async works. What you could do is to write a flag to a file and return the response to the client right away. Have another process that polls the file and if the flag is set, does the processing of the "million items" as you say. Or you can start the process async from the client. Your client can do other things while you are processing the "million items"
|
0

As the frontend will time out when called from there if it's not async (It makes millions of operations) I wish to use this controller task to run async operations.

Asynchronous code is not going to help you (see the section "Not a Silver Bullet"). In summary, async on ASP.NET is a way to yield to the server's thread pool - it is not a way to yield (or return) to the client/browser.

There are a few approaches to returning early from ASP.NET requests, but most of them are dangerous to some degree or another. Since you already have a database, I'd recommend looking at HangFire. Note that your HangFire processing should be done outside ASP.NET - e.g., in an Azure Worker Role or Win32 Service.

Comments

0

For making any synchronous method to behave like async, just add two things, in method signature replace void with Task. and at the end of the method write return Task.CompletedTask;.

Final implementation is like

   public Task ASimpleSynchronousMethod(){
     // TO DO

     // Add this additional line at the end of the method body
     return Task.CompletedTask;
   }

Hope this will work.

Comments

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.