简体   繁体   English

使线程等待退出而不诉诸Thread.Sleep()

[英]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: 您当前的Main方法可以更简单地重写为:

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? StartProgram已经在等待进程退出...为什么要引入一个新线程? 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. Process.WaitForExit()没有失败模式。 It's solid, this is rock in the Windows API. 它很稳固,这是Windows API中的摇滚。 So program.exe really did exit. 所以的Program.exe 真的退出。 If you still see side-effects of the program after WaitForExit() returned then program.exe is probably a single-instance app. 如果在WaitForExit()返回后仍然看到程序的副作用,那么program.exe可能是一个单实例应用程序。

The canonical example of a single-instance app is Microsoft Word. 单实例应用程序的规范示例是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. 它已经过优化,即使您打开多个文档,也只会运行一个msword.exe实例。 This works by msword.exe starting up small and checking if another instance is already running. 这可以通过msword.exe启动小并检查另一个实例是否已在运行。 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. 在启动它之前杀死任何正在运行的program.exe实例将是一个非常Q&D的解决方案。

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(). 我认为使用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. 这里的t.join()要求主线程等到线程t完成其处理,这与你想要的完全相反。

maybe i got something wrong here. 也许我在这里弄错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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