views:

130

answers:

5

Hello,

I'm having a problem trying to wrap my head around what I'm doing wrong while attempting a simple threading operation in one of my applications.

Here's what I'm after: I want the main thread to spawn a separate thread; that separate thread will open a program, feed that program an argument (a filename) and then once that program closes, the child thread will terminate and the main thread can continue it's work. I've created a very simple code example to illustrate. And truely, it doesn't even really HAVE to be a separate thread, it just needs to wait until the program is done with it's work. What am I doing wrong here? Any help would be most appreciated!

 class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Opening....");

        var t = new Thread(StartProgram);
        t.Start();
        t.Join();

        Console.WriteLine("Closed");
        Console.ReadLine();
    }

    private static void StartProgram()
    {
        var startInfo = new ProcessStartInfo();
        startInfo.FileName = @"c:\program.exe";
        startInfo.Arguments = @"file.txt";

        var p = Process.Start(startInfo);
        p.WaitForExit();
    }

}
+9  A: 

Why do you bother launching a separate thread? Your current Main method can be rewritten more simply as:

static void Main(string[] args)
{
    Console.WriteLine("Opening....");

    StartProgram();

    Console.WriteLine("Closed");
    Console.ReadLine();
}

StartProgram is already waiting for the process to exit... why introduce a new thread? Perhaps I'm missing something...

Jon Skeet
Good point - I assumed the main thread did something beyond waiting.
Brian Rasmussen
Dammit! I was about to post an answer, but of course, Jon Skeet did it first :)
andrecarlucci
+1  A: 

You actually should NOT be using a separate thread there. You specifically want your main thread to block while it waits, which is the opposite of why you would use a thread.

Andrew Barber
+1  A: 

I think you are answering your own question, why spawn off another thread?

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Opening....");

        var startInfo = new ProcessStartInfo();
        startInfo.FileName = @"c:\program.exe";
        startInfo.Arguments = @"file.txt";

        var p = Process.Start(startInfo);
        p.WaitForExit();

        Console.WriteLine("Closed");
        Console.ReadLine();
    }

}
MarkisT
Yes, it's true, I don't really have to spawn a separate thread here, I just need the main thread to be blocked while the program launches, processes the file, and exits. Unfortunately, as soon as the process is created, it exits immediately without waiting for the spawned program.
Robert Iver
@Robert: The code you've given will wait for the process you launch to finish. Is it possible that that's just a wrapper which creates *another* process?
Jon Skeet
A: 

Ideally however you main thread should wait till child thread complete their tasks before exiting. I think is some confusion over the use of join(). the t.join() here is asking the Main thread to wait till the thread t completes its processing which is exactly opposite of what you want.

maybe i got something wrong here.

frictionlesspulley
+2  A: 

Well, posting code that uses a thread and then saying in your question that you don't actually need it was not a great idea :)

Let's focus on the real problem. Process.WaitForExit() has no failure mode. It's solid, this is rock in the Windows API. So program.exe really did exit. If you still see side-effects of the program after WaitForExit() returned then program.exe is probably a single-instance app.

The canonical example of a single-instance app is Microsoft Word. It's a big program that requires lots of machine resources, running multiple instances of it can quickly consume them. It was optimized so that only one instance of msword.exe ever runs, even if you open multiple documents. This works by msword.exe starting up small and checking if another instance is already running. If there is, it talks to it using an interprocess communication facility like named pipes to tell the first instance to open the file. After which it quickly exits.

Not much you can do about this. Killing any running instance of program.exe before you start it would be a very Q&D solution.

Hans Passant
I know for a fact that there is not a competing instance of program.exe on the machine, but perhaps maybe what is going on is program.exe is a stub for some other executable...just had that thought...
Robert Iver
+1: This is the only answer that even attempts to address the root problem. The others talk about how there is no need for a separate thread which the OP already acknowledged.
Brian Gideon