locked
Windows Service hangs python script execution RRS feed

  • Question

  • Hi there

    Currently i have a windows service that preforms some database operations via entity framework fallowed by the execution of a python script.

    This script runs very well directly in the command line (cmd.exe). It happens that it hangs almost every time when run from the windows service or a console application.

    My guess is that the problem related to threads. I’ll try to be concise and not to paste to many code but here it is:

    In the windows service I have a threaded timer (System.Threading.Timer) that ticks until a given hour, and then starts the worker process that executes the database operations and python execution:

    //Locker to prevent more than one worker process at the same time
    private readonly object locker = new object();
    …..
    
    public void Worker(object state)
    {
    
       if (Monitor.TryEnter(locker))
       {
         try
         {
    
    	//Should i run?
    	var now = System.DateTime.Now;
    
    	if (now < timeToRun.AddMinutes(5) && now > timeToRun.AddMinutes(-5))
    	{
                  //Run the process
    	     ExecuteWorkerProcess();              
    	}
    
           }
           catch (Exception ex)
           {
    	logger.LogException(...);
            }
            finally
            {
    	Monitor.Exit(locker);
             }
         }
    
    }
    

    Inside the worker process is this:

    …..
    //Async as in with events
    IAction script = new AsyncPythonScript(arguments, fileName, scriptFolder, logger);
    script.Execute();
    …..

    Now, the part that hangs:

    public void Execute()
    {
    	proc = new System.Diagnostics.Process();
    
    	try
    	{
    
    		if (!System.IO.Directory.Exists(scriptFolder))
    		{
    			logger.LogWarning(String.Format("Could not find {0} directory ", scriptFolder));
    			return;
    		}
    
    		System.IO.Directory.SetCurrentDirectory(scriptFolder);
    
    		logger.LogDebug(String.Format("Current execution directory:{0}", System.IO.Directory.GetCurrentDirectory()));
    
    		ProcessStartInfo arg = new ProcessStartInfo()
    		{
    			Arguments = string.Concat(scriptFolder, @"\", arguments),
    			FileName = fileName
    		};
    
    
    		logger.LogDebug("Process parameters:");
    		logger.LogDebug(String.Format("Arguments:{0}", arg.Arguments));
    		logger.LogDebug(String.Format("FileName:{0}", arg.FileName));
    
    
    		proc.StartInfo = arg;
    
    		proc.StartInfo.UseShellExecute = false;
    		proc.StartInfo.CreateNoWindow = false;
    		proc.StartInfo.RedirectStandardOutput = true;
    		proc.StartInfo.RedirectStandardError = true;
    		proc.StartInfo.RedirectStandardOutput = true;
    
    		proc.EnableRaisingEvents = true;
    		proc.Exited += new EventHandler(proc_Exited);
    
    		proc.Start();
    
    
    		logger.LogDebug("Async process started.");
    
    	}
    	catch (Exception ex)
    	{
    		logger.LogException("Exception from python process:", ex);
    
    		//try kill the process
    		try
    		{
    			if (proc != null)
    			{
    				proc.Close();
    				proc.Dispose();
    
    				logger.LogDebug("Process closed and disposed of.");
    			}
    		}
    		catch //if we cant dispose the process it´s because there is nothing to dispose
    		{
    		}
    	}
    
    }
    
    
    
    void proc_Exited(object sender, EventArgs e)
    {
    
    	logger.LogDebug("Process exited");
    
    	try
    	{
    
    		string stderr = proc.StandardError.ReadToEnd();
    		string stdout = proc.StandardOutput.ReadToEnd();
    
    
    		logger.LogDebug("Dump from python output");
    		logger.LogDebug(stdout);
    
    		if (!string.IsNullOrEmpty(stderr))
    		{
    			logger.LogWarning("Error log from python process:" + stderr);
    		}
    
    		proc.Close();
    		proc.Dispose();
    		logger.LogDebug("Process closed and disposed of.");
    	}
    	catch (Exception ex)
    	{
    		logger.LogException("An exception was thrown when the process exited", ex);
    	}
    }

    In this case the exit event is never reached.

    I have tried to run this with proc.WaitForExit() and the result is the same, the process never ends......

    Can anyone of you see something I don’t?

    Thanks


    Jorge Vinagre

    Friday, September 6, 2013 2:42 PM

Answers

  • Hello,

    Thanks for your posting.

    From your description, I know that you encounter some issue when you run your code. I try to  debug your code and find  the error code : proc.Start() ,because you  create a new thread in Windows Service , then  execute proc.Start() event but it fails  so that proc.WaitForExit()  event can 't be triggered  .I would like to suggest you can try to use  CreateProcessAsUser function   that Creates a new process and its primary thread. The new process runs in the security context of the calling process.
    Hope these help.

    Lilia Gong <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Tuesday, September 24, 2013 2:55 PM