Windows station



  • The following problem has arisen with the operation of the service windows. I haveve got windows a service that performs a complex statistical analysis with multiple servers. The analysis shall be carried out in time (system.timers.timerin method OnStart♪ The time of one analysis is quite high (may be 20 minutes). The problem is to stop this service. If you try to stop her at a time when the analysis is under way, she's hung up and running or getting her out of the system is getting very problematic. If you stop her at the moment of simplicity, she's successfully completing her work.

    There's a method in the service. OnStopbut I don't understand how this analysis can be stopped using this method. Advise a solution to this problem.



  • Possible crutches:

    1. Make Thread.Abort() background flow
    2. Put IsBackground = true

    In both cases, you will have to give up the standard timer for your flow. In this flow, you're going to have to roll an endless cycle with Thread.Sleep between the challenges.

    These crutches were bad enough to leave the background process in a bad state. For example, he can record half of the information in the OBD system, and the rest can't succeed or anything. But if the nature of the process is such that it can be interrupted at any time, it can be used.


    It's about the right way. The cause of the problem is next.

    The main method of your service is probably around:

    static void Main() {
      ServiceBase.Run(new FooService());
    }
    

    When FooService receives a stop signal - it's closed, and ServiceBase.Run completes work. This leads to the completion of the Main method, but the background flow remains.

    What does the service dispatch see? The process continues to work, so no new start can be made. But control signals don't take the old process either. ♪ ♪

    Two actions must be taken to avoid this situation.

    1. It is advisable to interrupt the task of analysing the Stop signal.
    2. To wait for the end of the baseline before exiting OnStop.

    The first paragraph is needed so that the service can be completed faster than 20 minutes, the second one so that it doesn't look obsessed.


    In order to correctly interrupt the task of analysis, such an interruption should be provided in the analysis algorithm itself. For example, I'll have a flag and check it periodically.

    But there's a better way, and it's called... https://msdn.microsoft.com/ru-ru/library/system.threading.cancellationtoken(v=vs.110).aspx ♪ Well, to wait for the end of processing, it's convenient to create a new flow and wait for it.

    This is an example of this service:

    class FooService {
      private readonly CancellationTokenSource ctsStop = new CancellationTokenSource();
      private Thread thread;
    

    protected override OnStart(string[] args) {
    thread = new Thread(ThreadProc) { IsBachground = false };
    thread.Start(ctsStop.Token);
    }

    protected override void OnStop() {
    ctsStop.Cancel(); // Отменяем выполнение задачи, если она запущена
    thread.Join();
    }

    private void ThreadProc(object obj) {
    var token = (CancellationToken)obj;
    do {
    RunTask(token);
    } while (!token.WaitHandle.WaitOne(...));
    }

    private void RunTask(CancellationToken stopToken) {
    // тут ваша аналитика
    }
    }

    The task should be periodically reviewed stopToken.IsCancellationRequestedand if she's returned true, then we need to get rounded up fast.

    If you have to wait, instead. Thread.Sleep Better do it. stopToken.WaitHandle.WaitOne

    Well, plus, you can sign up for the event of annulment. stopToken.Register (but in order to avoid memory leaks, all such challenges need to be done in an using block).


Log in to reply
 


Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2