0

I am writing a windows service which creates a couple of parallels tasks to run: Following is the sample code snippet:

       private static void TaskMethod1()
       {
          //I am doing a bunch of operations here, all of them can be replaced with a sleep for 25 minutes
       }

       private static async Task TaskMethod()
       {
           while(runningService)
           {
              // Thi will create more than one task in parallel to run and each task can take upto 30 minutes to finish
              Task.Run(() => TaskMethod1(arg1);
           }
       }
       internal static void Start()
        {
            runningService = true;
            Task1 = Task.Run(() => TaskMethod());
        }

        internal static void Stop()
        {
            runningService = false;
            Task1.Wait();
        }

Now when I stop the service, it will not create any new tasks because runningService = false but windows service doesn't wait for 30 minutes for already running tasks to get finished.

Now I read that there is an x minutes timeout for service and it can be changed using registry settings, I was just wondering if there is the way such that the service will wait for each task to be finished instead of hardcoding that time via the registry.

sporty_1993
  • 133
  • 10
  • Try looking at this: https://stackoverflow.com/questions/15149811/how-to-wait-for-async-method-to-complete – sr28 Apr 14 '20 at 09:06
  • @sr28 the link mentions the wait for tasks, I am concerned about the wait time while stopping a service. Service itself has a wait time which is much lesser than what the task running requires. – sporty_1993 Apr 14 '20 at 09:08
  • 2
    So, the running tasks should run to end before stopping the service? If so, I'd _not_ use "Stop" - it will timeout. I'd use a [custom command](https://learn.microsoft.com/en-us/dotnet/api/system.serviceprocess.servicebase.oncustomcommand?view=netframework-4.8) to request graceful shutdown. – Fildor Apr 14 '20 at 09:15
  • @Fildor, Yes that is my requirement. As soon as I stop the service using the management console before the service stops, it should wait for all the running tasks to be finished. – sporty_1993 Apr 14 '20 at 09:17
  • It is not clear what is the requested case. In general, you have three options: #1: ignore incomplete tasks, #2: wait for them to finish no matter how long will it take, #3: wait for them to finish, but specify max waiting time – Tomas Chabada Apr 14 '20 at 09:19
  • @TomasChabada #2 is impossible, because a windows service is expected to return from Start / Stop implementation in a specified amount of time. Otherwise the system will consider them "unresponsive". So if you want to wait indefinitely, you need to use some other means to request a graceful shutdown. – Fildor Apr 14 '20 at 09:21
  • @TomasChabada Yes option2 would be very much ideal for me but as Fidor said I tried to do that but couldn't find a way that is why I was left with the option 3. But in the end, I want all tasks to be finished and not abandoned in the middle. – sporty_1993 Apr 14 '20 at 09:35
  • Could you include the code of `TaskMethod1` in your question? – Theodor Zoulias Apr 15 '20 at 03:51
  • @TheodorZoulias It takes around 25 minutes to get finished, there are bunch of operations, but I assume code for TaskMethod1 is irrelevant to what I am asking right? – sporty_1993 Apr 15 '20 at 16:40
  • Now it's OK. I just wanted to see the signature of the method. – Theodor Zoulias Apr 15 '20 at 16:44
  • Seeing how the `TaskMethod` is implemented, it seems like it's scheduling tasks in a tight loop. From what I understand it will schedule tens of millions of tasks for every second that the `runningService` will be true. Is this the intended behavior? – Theodor Zoulias Apr 15 '20 at 16:48
  • @TheodorZoulias there can be 12 tasks in parallel and each can take upto 30 minutes but as soon as I stop i,e, `runningService` is `false`, it will not create new tasks, hence I just need my service to wait at max 30 minutes – sporty_1993 Apr 15 '20 at 16:54
  • 12 tasks will be running because there are 12 threads initially in the `ThreadPool` (I guess that you have a 6-core processor with hyperthreading). But there will be also some hundred millions tasks scheduled. Check the RAM usage of your program if you don't believe me. There should be tons of memory allocated! – Theodor Zoulias Apr 15 '20 at 17:05

1 Answers1

-2

In my .net core services i use the interface IHostApplicationLifetime to intercept when my service is beign closed, by registering an action to call using IHostApplicationLifetime.ApplicationStopped.Register(Action callback) . Then in the callback you could wait for the task to complete.

LMio
  • 126
  • 1
  • 9
  • A _windows service_ is not the same as a .net core service. Unfortunately, those terms create some confusion. Even if you implement a windows service with a .netCore Service, it would still be expected to return from the "stop" within a certain timeframe. – Fildor Apr 14 '20 at 09:30