【问题标题】:How to start a Process in a Thread如何在线程中启动进程
【发布时间】:2019-11-26 15:32:38
【问题描述】:

进一步编辑 以下不是生产代码——我只是在玩几个类,试图弄清楚我如何在线程中运行进程——或者即使这是可行的。我已经阅读了 MSDN 上的各种定义,但我是线程和进程的新手,因此对文章的任何进一步明确参考将不胜感激


这很好......

class Program {
    static void Main(string[] args) {

        Notepad np = new Notepad();
        Thread th = new Thread(new ThreadStart(np.startNPprocess));
        th.Start();

        Console.WriteLine("press [enter] to exit");
        Console.ReadLine();
    }
}

public class Notepad {

    public void startNPprocess() {

        Process pr = new Process();
        ProcessStartInfo prs = new ProcessStartInfo();
        prs.FileName = @"notepad.exe";
        pr.StartInfo = prs;
        pr.Start();     

    }
}

这不是……

class Program {
    static void Main(string[] args) {


        Process pr = new Process();
        ProcessStartInfo prs = new ProcessStartInfo();
        prs.FileName = @"notepad.exe";
        pr.StartInfo = prs;

        ThreadStart ths = new ThreadStart(pr.Start);
        Thread th = new Thread(ths);
        th.Start();


        Console.WriteLine("press [enter] to exit");
        Console.ReadLine();
    }
}

为什么第二个和第一个不一样?在第二个脚本中,我尝试使用 Threadstart 委托传递Process.Start ...我认为这可以作为void 方法吗? 第一个脚本是唯一的选择还是我可以稍微更改第二个脚本,以便它有效地完成与第一个脚本相同的工作,即在指定线程中启动记事本实例?


编辑

关于为什么的一些背景知识我在玩这个代码:最终我需要构建一个应用程序,它将同时运行多个 Excel 进程。当 VBA 出错时,这些过程可能会很麻烦,因为它会导致一个对话框。所以我想如果每个进程都在一个线程中运行,那么如果一个特定的线程已经运行了太长时间,那么我可以杀死该线程。我是线程/进程的新手,所以目前基本上是在玩各种可能性。

【问题讨论】:

  • 从另一个线程启动进程有什么好处?为什么不简单地从当前线程启动进程?结果将是相同的,因为启动进程不会等待其完成。
  • Process.Start 不是 void 方法,它返回 bool。
  • 关于您的编辑,您不应该使用 COM 自动化 Excel(或者更好的是,使用 open xml SDK 完全不使用 excel),而不是开始一个新流程?
  • 或者只是不自动化 Excel ...support.microsoft.com/kb/257757(是的,它用于服务器端的东西,但它似乎适用于这里)
  • 这是对您的编辑的评论,您可以禁用 excel 中的大多数对话框,因此它们不会弹出,除非您希望它们弹出

标签: c#


【解决方案1】:

ThreadStart 需要一个返回 void 的委托。 Process.Start 返回bool,因此不是兼容的签名。您可以使用 lambda 来吞入返回值,该 lambda 为您提供正确返回类型的委托(即void),如下所示:

    Process pr = new Process();
    ProcessStartInfo prs = new ProcessStartInfo();
    prs.FileName = @"notepad.exe";
    pr.StartInfo = prs;

    ThreadStart ths = new ThreadStart(() => pr.Start());
    Thread th = new Thread(ths);
    th.Start();

...但可能建议检查返回值:

    ThreadStart ths = new ThreadStart(() => {
        bool ret = pr.Start();
        //is ret what you expect it to be....
    });

当然,一个进程在一个新进程(完全独立的线程束)中启动,所以在一个线程上启动它是完全没有意义的。

【讨论】:

  • 投反对票的人,请解释您认为此答案有什么问题,以便我改进。
  • +1 @Spender 感谢您花时间在这上面 - 我的 OP 目前是 -3...似乎有一些热心的匿名反对者!
  • 酷,这是我需要的线路! ...Of course, a process starts in a new process (a completely separate bunch of threads), so starting it on a thread is completely pointless.
  • 如果我的线程是一个 telnet 进程并且我需要在我的其他应用程序没有被阻塞的情况下读取输出,这并不是毫无意义的。如果我开始进程等待文本......但仍需要发送命令并等待更多响应,它只会阻塞,因为 telnet 永远不会结束进程。因此,从另一个线程开始并从另一个进程线程委托输出,通过我的线程向下传递给客户端,这是有道理的,直到我显式调用 exit,杀死两个线程。但是..这是正确的方法吗..不知道。 MS 将其称为交互式协议进程,但没有示例如何处理它。
  • 不确定以上是否完全正确。来自 msdn “一个处理器执行线程,而不是进程,因此每个应用程序至少有一个进程,而一个进程总是至少有一个执行线程,称为主线程。”
【解决方案2】:

你可以做出改变

ThreadStart ths = new ThreadStart(delegate() { pr.Start(); });

【讨论】:

    【解决方案3】:

    使用此代码正常启动该过程:

    Process.Start("notepad.exe");
    

    创建线程来运行新进程没有任何意义,也没有任何好处。这就像在您可以直接执行“cmd.exe”时运行一个执行“cmd.exe”的批处理文件......您只是在做更多不必要的事情。不要重新发明轮子,玩得轻松:P

    【讨论】:

    • +1 感谢您的帮助;似乎很多人不理解我的问题 - 目前 -3 !
    • 这段代码的好处是我正在玩弄这些类,试图了解它们的作用——这不是生产代码——我只是想弄清楚我如何在线程中运行进程- 如果可以的话?
    • 当然可以。但如果你问我好不好,我会回答没有。这没有道理。线程适用于运行应用程序代码,而不是外部进程。
    【解决方案4】:

    不直接回答 OP,但由于这个帖子帮助我找到了正确的方向,我确实想回答这个问题:

    “在线程上启动它完全没有意义”

    我有一个使用 NodeJS 作为其 TCP 套接字管理器的 .Net 服务器。我希望 NodeJS 写入与 .Net 服务器相同的输出,并且它们都并行运行。所以在新线程中打开允许我使用

    processNodeJS.BeginErrorReadLine()
    processNodeJS.BeginOutputReadLine()
    processNodeJS.WaitForExit()
    

    同时不阻塞 .Net 服务器的主线程。

    我希望它对某人有意义,如果您有更好的方法来实现我刚刚描述的内容,我会非常高兴听到。

    【讨论】:

      【解决方案5】:

      您可以使用下面这段代码中的 start 关键字在另一个线程中启动进程:

      Process.Start("start notepad.exe");
      

      这样,当您运行记事本时,您的 GUI 程序不会冻结。

      【讨论】:

        猜你喜欢
        • 2013-06-22
        • 2016-10-08
        • 2017-05-12
        • 1970-01-01
        • 2019-01-03
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多