简体   繁体   中英

Making thread wait for exit without resorting to Thread.Sleep()

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();
    }

}

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...

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.

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.

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();
    }

}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM