1

I wanted to get some basic .NET MVC understanding so I started working on a very simple application that is somewhat similar to Yelp. It consists of a User object and Business object. A user can add businesses to their "watch list" and when someone creates a review for that business the application would look through a table of "user id-business id" relations and email the users that are watching that business for new reviews (so that they can respond to them).

In my ReviewsController, I have a Create action that creates a review. Before that action returns, I would like to run a method that checks if there are any watches for the business the review was just created for.

This is where I get stuck because I'm not sure what would be a good way of doing this in MVC setting(?).

What I do know is that the user who is creating the review does not need to wait for the application to look through the "user-business" relation table.

Would it be a good idea to create this lookup functionality as an async method? I also looked into events but seems like events are not ideal in MVC setting. Are there any well-established patters in MVC world for situations like these?

  • 1
    This is one of those scenarios where an `async void` method would be appropriate. It's essentially fire-and-forget. – Barry O'Kane Dec 05 '17 at 17:49
  • 1
    See [this article](https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx) for an overview of different methods, and [this question](https://stackoverflow.com/questions/17577016/long-running-task-in-webapi) for caveats of using fire-and-forget tasks – Jonathan Tyson Dec 05 '17 at 18:14

3 Answers3

2

@Jonathan Tyson pointed out this article which shows some great options for background taks.

I am thinking of going with QueueBackgroundWorkItem as it seems to be a good fit for my scenario. It is already build in with .Net 4.5.2 and it does everything I am looking for.

Beware of the 90 second limit on it (might not be a great solution for everyone). In my case it is more than enough time.

1

Another way of doing it, is to use ajax in View. Ajax is designed to be async, therefore, it is suitable for your use.

Whenever the post review button is clicked, an ajax request is sent to server to perform the CheckWatches action in parallel.

Here is a link to a simple example of an ajax call:

Making a Simple Ajax call to controller in asp.net mvc

oopsdazie
  • 716
  • 1
  • 7
  • 22
  • Would I have to know that the Create [HttpPost] action was successful? I wouldn't want to fire the Ajax call every time I click on the button because the Create could fail and the review never created in the first place. –  Dec 05 '17 at 18:12
  • Then, trigger the ajax call in the view shown after the Create action is succeeded, – oopsdazie Dec 05 '17 at 18:56
-2

You can use the Task Parallel Library to create asyncronous tasks. The following code executes the CreateReview method, when it finishes creates a thread and executes the method CheckWatches. At the same time it returns the action Create whitout waiting the new thread finishes.

public ActionResult Create()
{
     // User related task
     CreateReview();
     Task.Factory.StartNew(() =>
      {
               // system related task 
             CheckWatches();       
      });

    return View();
}
anmarti
  • 5,045
  • 10
  • 55
  • 96
  • 1
    Note that fire-and-forget is generally bad idea as there is no way to know if operation succeeds and sometimes it can lead to simply terminating process on failures... Also if `CheckWatches` mistakenly accesses any request's data it will blow up spectacularly in 37% of cases. – Alexei Levenkov Dec 05 '17 at 17:43
  • I really wonder what the better way is if using Task parallel is not suitable. – oopsdazie Dec 05 '17 at 18:00