0

I have mvc application which is hosted on azure webapp

I have simple start button and stop button.

When you click start button it send message to iot hub

When you click stop button it stop sending messages.

I achieve this using bool flag values true and false.

Now issue is when I click stop button it set flag false but unable to reflect flag value false into while loop ?

public class HomeController : Controller
    {
        bool flag;
        static Thread mythread;
         [HttpPost]
        public async Task<ActionResult> Start()
        {
           flag = true;
           if (messageType.Contains("demo1"))
            {
                mythread = new Thread(async () => await ProcessStart("data1",flag));
                thread.Start();
            }
            
        }
        
         private static async Task ProcessStart(string message,bool flag)
        {

            while (flag)
            {                

                    await deviceClient.SendEventAsync(message);
                
            }
        }
        
         [HttpPost]
        public ActionResult Stop()
        {
            mythread.Abort(); // still unable to kill started thread :(
            flag = false;
           return View("Index");
        }

but after stop click also flag value in while loop is true :( how ? I can not use static here as it will false all flag variable value gloably.

I wonder why can not i track thread id and save somewhere like in hidden field or temp and kill that same thread when i click on stop button ?

Community
  • 1
  • 1
Neo
  • 15,491
  • 59
  • 215
  • 405
  • 3
    Controllers get instantiated per request. The `flag` will never be `true` for another request. Is your actual question _"How to start a background job from ASP.NET MVC and communicate with that job"_? Then research that first. – CodeCaster Nov 05 '18 at 15:52
  • no when i click on stop flag value is not reflected as false into while loop as its not static variable what should i do to get false in while loop when i click on stop.(if i make flag variable static it will work but then all instances get false) – Neo Nov 05 '18 at 15:54
  • removed flag=true from homecontroller.cs still unable to set false after click stop why? – Neo Nov 05 '18 at 16:08
  • can i use static variable for thread on controller level and kill that thread on stop method ? – Neo Nov 05 '18 at 17:05

1 Answers1

3

From Bruno's answer on your other similar question:

If you're saying that one request starts the while loop, and you want another request to stop it, then that's not possible with a ASP.NET MVC as it is stateless. Once the view is returned your while loop is no longer running. In your case, it only looks like it's taking a minute for the StopLoop method to get hit. What's probably really happening is that your while loop is probably running endlessly, IIS kills it, and then the stop loop request is processed.

To reiterate that in other words: Each time you send a request, your controller is instantiated as a new object. This means that the private variable flag is not shared between those objects. On your second request, when you click the End button, you are not interacting with the same controller object that was used when you clicked the Start button. Thus, setting the flag to false on the End button click has no effect on the while loop from the previous controller object.

I suggest you read about the life cycle of the MVC controller to better understand what is happening between these requests.

MVC life cycle

Each time you send an HTTP request, the MvcHandler creates a new controller. This should illustrate my point above: the two objects are not connected and changing the flag variable on one has no effect on the other.


Since the essence of your question is how to run a background task in ASP.NET, you should try searching for that instead.

Jack
  • 1,453
  • 1
  • 15
  • 35
  • thanks for broad explanation. can i use two separate browsers ? and use static variable flag in that case as it will be two separate instances ? – Neo Nov 05 '18 at 18:11
  • 2
    MVC is stateless. Trying to persist any data (including your while loop) between requests will make it stateful, which is arguably bad. If you want to make it stateful, you will have to do that through session or temp data. For what you're doing, you cannot persist a controller across multiple requests. It just doesn't work that way. I would recommend you create a windows service that runs the background task (or read some of the other options in the link I sent) and then communicate with that service. Then, you could send the flag to the service and it could start / stop your loop. – Jack Nov 05 '18 at 18:16
  • 2
    Another possible option is to implement the loop using JavaScript on the client. But I can't say that would work for sure. – Jack Nov 05 '18 at 18:17
  • because if i use static variable it works but when stop it will stop for all as you said i got your point. any simple implementation link you can share or include any code snippet for mvc ? that will be great thanks in advance – Neo Nov 05 '18 at 18:19
  • I wonder why can not i track thread id and save somewhere like in hidden field or temp and kill that same thread when i click on stop button ? – Neo Nov 05 '18 at 18:24