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

2

6

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
    }
}
Semaphore answered 3/9, 2015 at 19:46 Comment(10)
I think you should post the intialization code for that worker .exe.Sucy
Updated - it's just standard (VS generated) init stuff until the form_load, at which point my stuff (normally) kicks in. Throwing the log call as the first line of form_load is how I figured out it wasn't reaching that point.Semaphore
Have you tried dumping the process when it's hung and loading into VS/WinDBG to find out where it's hanging?Enterprising
Have you tried running that WinForms program standalone to see if it starts up? I'm thinking you've got something wrong with the form definition itself that makes it impossible to initialize it.Sucy
Not yet - I don't normally need to do remote debugging so I'm not quite sure on all the available tools. Edit because shift+enter vs enter: I'll make some adjustments to the service and give it a try the next time it happens.Semaphore
@JeffPrince I have - it runs perfectly fine most of the time, and I've never seen it hang while debugging. Running it standalone is how I debug specific plugins too (since they're just class libraries). Edit: Just double checked via command prompt run too and it worked without issue.Semaphore
I wonder if it doesn't like that CreateNoWindow you specified.Sucy
@JeffPrince Possibly, it's been quite a while since I set the base of the system up - maybe a .Net update that changed behavior? I set the service to save a dump with the log it creates when it sees a hung process - I'll see if that reveals anything tomorrow morning and follow up here.Semaphore
Updated question with dump info. Thinking I'm going to look into swapping the worker to a console app, or seeing what I can adjust with the startup of it.Semaphore
(I can finally comment :D) Saw the last updates. Hope it works!Tympanites
S
1

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
    }
}
Semaphore answered 8/9, 2015 at 15:54 Comment(0)
T
2

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

Tympanites answered 4/9, 2015 at 15:59 Comment(2)
No problem, I understand the pain (only 11 rep right now). Grrr, Edit again because enter vs shift+enter: In this case the service is running with super admin credentials in the appropriate session.Semaphore
Did you get this information from you service ? Even microsoft couldn't solve our problem... We found out by trying multiple things desperate. Just in case, double check. At least, you will be sure :PTympanites
S
1

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
    }
}
Semaphore answered 8/9, 2015 at 15:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.