Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno .NET service (Dotaz na Wikana)

Ahoj,

mám službu (service) a potřebuji, aby se periodicky spouštěl proces.
Protože je nutné zabránit souběhu, je služba využita s proc.WaitForExit();

Bohužel proces sice funguje, ale nedá se řídit (zastavit/spustit) regulérně.
Nelekej se délky kódu, pes je zakopaný jen v metodě OnStart
Konkrétně mám:

  public class ServiceImplementation : IWindowsService
    {

        bool sluzbaJede;
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            sluzbaJede = false;
        }

        /// <summary>
        /// This method is called when the service gets a request to start.
        /// </summary>
        /// <param name="args">Any command line arguments</param>
        public void OnStart(string[] args)
        {
            Console.WriteLine("Prohledavam databazi...");

            sluzbaJede = true;
            ProcessStartInfo start = new ProcessStartInfo();
            // Enter in the command line arguments, everything you would enter after the executable name itself
            start.Arguments = "-f d:\\Programy\\EasyPHP-Devserver-17\\eds-www\\telnet\skript.php";
            // Enter the executable to run, including the complete path
            start.FileName = "d:\\Programy\\EasyPHP-Devserver-17\\eds-binaries\\php\\php5630vc11x86x190305170114\\php.exe";
            // Do you want to show a console window?
            start.WindowStyle = ProcessWindowStyle.Hidden;
            start.CreateNoWindow = true;
            int exitCode;


            // Run the external process & wait for it to finish
            using (Process proc = Process.Start(start))
            {
                proc.WaitForExit();
                // Retrieve the app's exit code
                exitCode = proc.ExitCode;
            }

            Console.WriteLine("Prohledavani dokonceno.");

            if (sluzbaJede == true)
            {
                this.OnStart(null);
            }

        }

        /// <summary>
        /// This method is called when the service gets a request to stop.
        /// </summary>
        public void OnStop()
        {
            sluzbaJede = false;
        }

        /// <summary>
        /// This method is called when a service gets a request to pause,
        /// but not stop completely.
        /// </summary>
        public void OnPause()
        {
            sluzbaJede = false;
        }

        /// <summary>
        /// This method is called when a service gets a request to resume 
        /// after a pause is issued.
        /// </summary>
        public void OnContinue()
        {
            sluzbaJede = true;
        }

        /// <summary>
        /// This method is called when the machine the service is running on
        /// is being shutdown.
        /// </summary>
        public void OnShutdown()
        {
            sluzbaJede = false;
        }

        /// <summary>
        /// This method is called when a custom command is issued to the service.
        /// </summary>
        /// <param name="command">The command identifier to execute.</param >
        public void OnCustomCommand(int command)
        {
        }
    }
}

Tuším, kde je potíž. Vadí mu nějakým způsobem to, kdy se proces OnStart neukončí. (Ano, tak je to napsané).

Lze z toho nějak jednoduše ven, aniž bych se musel prokousávat tunou materiálů o službách? :-)

Děkuji ! Děkuji za spolupráci, přátele,
Nakonec jsem to doňuchal nějak takhle:

 public class ServiceImplementation : IWindowsService
    {
        private static Timer Timer;
        bool sluzbaJede;
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            sluzbaJede = false;
            Timer.Stop();
        }

        /// <summary>
        /// This method is called when the service gets a request to start.
        /// </summary>
        /// <param name="args">Any command line arguments</param>
        public void OnStart(string[] args)
        {
            Timer = new Timer(2000); // every 40 seconds
            Timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            Timer.Start(); // <- important

            

        }

        private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Timer.Stop();
            Console.WriteLine("Prohledavam databazi...");

            sluzbaJede = true;
            ProcessStartInfo start = new ProcessStartInfo();
            // Enter in the command line arguments, everything you would enter after the executable name itself
            start.Arguments = "-f d:\\Programy\\EasyPHP-Devserver-17\\eds-www\\telnet\\skript.php";
            // Enter the executable to run, including the complete path
            start.FileName = "d:\\Programy\\EasyPHP-Devserver-17\\eds-binaries\\php\\php5630vc11x86x190305170114\\php.exe";
            // Do you want to show a console window?
            start.WindowStyle = ProcessWindowStyle.Hidden;
            start.CreateNoWindow = true;
            int exitCode;


            // Run the external process & wait for it to finish
            using (Process proc = Process.Start(start))
            {
                proc.WaitForExit();
                // Retrieve the app's exit code
                exitCode = proc.ExitCode;
            }

            Console.WriteLine("Prohledavani dokonceno.");

            Timer.Start();
        }

        /// <summary>
        /// This method is called when the service gets a request to stop.
        /// </summary>
        public void OnStop()
        {
            sluzbaJede = false;
            Timer.Stop();


...... A tak dále..........
        }
Předmět Autor Datum
No moc jsem to nezkoumal ale: Timer = new Timer(2000); // every 40 seconds To je každé 2 sekundy a…
Wikan 13.03.2020 08:44
Wikan
Vidíš tam něco špatně ?! S tím timerem máš pravdu, zapomněl jsem opravit poznámku, ale kód je ok.…
Flash_Gordon 13.03.2020 10:33
Flash_Gordon
S tím Timerem se ti může stát, že to spustíš i když předchozí proces pořád běží.
Wikan 13.03.2020 12:21
Wikan
Obecně ano, ale teď jsem tomu zabránil, ne?
Flash_Gordon 13.03.2020 15:13
Flash_Gordon
Teď kde?
Wikan 13.03.2020 16:00
Wikan
Timer.Stop(); // Zabráníme dalšímu spuštění funkce/programu proc.WaitForExit(); // zastavíme službu…
Flash_Gordon 13.03.2020 16:53
Flash_Gordon
Teď jsem to vylepšil ještě takhle: if (Timer.Enabled == true) // Pokud Timer skutečně běží Timer.S… poslední
Flash_Gordon 13.03.2020 17:16
Flash_Gordon

Vidíš tam něco špatně ?!

S tím timerem máš pravdu, zapomněl jsem opravit poznámku, ale kód je ok.

Jinak je tam něco špatně?
Jde o to, že kód se má provádět postupně a nesmí dojít k souběhu.
Zkoušel jsem to jen chvilku a pracovalo to ok.

Kód, který spustím a čekám na WaitForExit se sice provede až po 2s, ale
pak regulérně čekám, až doběhne. V tomto okamžiku by se provádění mělo zastavit
a navíc jako první volám Timer.Stop() takže pokud tam není chyba, nic by nemělo
běžet dál. A jakmile proces doběhne, tak odstartuje další Timer (za 2s).

Doufám, nemám tam něco, co by způsobilo souběh či jiné chování, než popisuju.

Teď jsem to vylepšil ještě takhle:

 if (Timer.Enabled == true)  // Pokud Timer skutečně běží
                Timer.Stop();            // Zastav jej a pokračuj... :
            Console.WriteLine("Prohledavam databazi...");

            ProcessStartInfo start = new ProcessStartInfo();
            // Enter in the command line arguments, everything you would enter after the executable name itself
            start.Arguments = "-f d:\\Programy\\EasyPHP-Devserver-17\\eds-www\\telnet\\skript.php";
            // Enter the executable to run, including the complete path
            start.FileName = "d:\\Programy\\EasyPHP-Devserver-17\\eds-binaries\\php\\php5630vc11x86x190305170114\\php.exe";
            // Do you want to show a console window?
            start.WindowStyle = ProcessWindowStyle.Hidden;
            start.CreateNoWindow = true;
            int exitCode;


            // Run the external process & wait for it to finish
            using (Process proc = Process.Start(start))
            {
                proc.WaitForExit();                     // čekej, pozastav vlákno, dokud se spuštěný proces neukončí !
                // Retrieve the app's exit code
                exitCode = proc.ExitCode;
            }

            Console.WriteLine("Prohledavani dokonceno.");

            if( Timer.Enabled == false)       // Pokud je Timer vypnutý, zapni jej opět
            Timer.Start();

Zpět do poradny Odpovědět na původní otázku Nahoru