Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# app hangs randomly when called from Process.Start()

I have a Windows service set up to manage custom .Net tasks. Organization is:

-Windows Service monitors a schedule and starts a worker .exe as needed.

-Worker .exe (lightweight winform app) uses a command line argument to pull up a DLL (plugin) and run some code.

This has been working well for months. I recently migrated it to Server 2012 (from 2008 IIRC) - this may be unrelated but it's hard to tell. Since some time after the migration, I've encountered an issue where the worker .exe "starts" after being called by a process.start(), but doesn't reach my code. No errors or anything, it just seems to freeze during app load.

The service code that starts it is fairly standard.

// Create a temp folder and copy the executable to it
// (so the source exe isn't always in use and can be swapped out)

Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Path.Combine(temp.Path, Path.GetFileName(ExecutablePath));
psi.Arguments = CommandLineArgs.ConcatenateList(" ");
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo = psi;
p.Start();

// read standard output if necessary, kill and reschedule if appears to be frozen, etc.

At that point, the worker executable starts up - it appears mostly normal in the task manager. The only thing that tips me off that something's gone wrong is the memory consumption - under normal circumstances the worker hits around 5MB during launch and grows to reflect the task, but when the process freezes it only reaches around 2MB and stops.

As proof that it's not any of my code in the worker, I've added a call to a logging function as the very first line and never seen a log.

There are no error messages, and - the really strange bit - it isn't a consistent issue. The exact same call that freezes now will run fine 30 seconds later. There also doesn't appear to be any true pattern to when the issue occurs either - the closest thing I'm seeing is that it occasionally happens to multiple tasks at once (e.g. it might be affecting all tasks started at the time when the issue occurs with any task).


I have it at a point where the service can automatically detect it and handle it appropriately, so it's not an urgent issue, but still something I'd like to fix if a cause or solution stands out to anyone.


Init code of worker is just a standard win forms startup, with my stuff starting to get called in form_load.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

public Form1()
{
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
    // Do Stuff - never gets hit when the freeze happens.
}

Edit: Per comments, set up the service to log a minidump with the log entry it creates when it sees a hung process. Will check on it tomorrow and see what comes of it.


Edit Sept 4, 2015: Minidump info:

The minidump shows the code stopped/stuck at the exiting } of static void main, i.e.:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
} // <------ This is where the main thread is frozen.

Everything seems fine otherwise.

I'm going to do some research and try some changes to the worker just in case.


Edit Sept 4 2015 #2: Adjusted the worker startup and it seems to be working. The gist of it is removing the Form reference and just using application context (e.g. codeproject sample)

I pounded the system with task requests and it didn't have any issues. I'll let it run over the weekend as a test and do a status update on Tuesday. Still curious about why it would randomly break like that with the form load.

Code as it stands now:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.Run(new AppContext());
    }
}

class AppContext : ApplicationContext
{
    public AppContext()
    {
        // Do Stuff
    }
}
like image 496
user1874135 Avatar asked Sep 03 '15 19:09

user1874135


2 Answers

I can't add a comment on your post yet (I'll be destroyed by other stackoverflow user for doing that but...)

I encounter a problem quite similar to yours. My problem was coming from the Session where the service is Started. During the migration, the service started in a "Session 0" in the new OS and not as a "system" program. It was issuing with the permission of our program to run through the service. Maybe you should check this point.

Sorry if I tell it as an answer and not in comment

like image 168
Pomme De Terre Avatar answered Nov 08 '22 12:11

Pomme De Terre


Per last note, pulling the form bit out of it all together appears to have fixed the issue. At this point I'm assuming that server 2012 doesn't like something about a winform app not being displayed in certain situations; since it worked most of the time and nothing had changed in the form's code.

Service:

// Create a temp folder and copy the executable to it
// (so the source exe isn't always in use and can be swapped out)

Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Path.Combine(temp.Path, Path.GetFileName(ExecutablePath));
psi.Arguments = CommandLineArgs.ConcatenateList(" ");
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo = psi;
p.Start();

// read standard output if necessary, kill and reschedule if appears to be frozen, etc.

Worker:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.Run(new AppContext());
    }
}

class AppContext : ApplicationContext
{
    public AppContext()
    {
        // Do Stuff
    }
}
like image 27
user1874135 Avatar answered Nov 08 '22 12:11

user1874135