11

进一步编辑 以下不是生产代码——我只是在玩几个类,试图弄清楚我如何在线程中运行进程——或者即使这是可行的。我已经阅读了 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();
    }
}

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


编辑

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

4

5 回答 5

28

AThreadStart期望一个返回的委托voidProcess.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....
    });

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

于 2013-01-22T09:45:57.847 回答
7

你可以做出改变,比如

ThreadStart ths = new ThreadStart(delegate() { pr.Start(); });
于 2013-01-22T09:56:25.517 回答
3

只需使用以下代码正常启动该过程:

Process.Start("notepad.exe");

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

于 2013-01-22T09:50:13.847 回答
3

不直接回答 OP,但由于这个线程帮助我跟踪正确的方向,我确实想回答这个问题:

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

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

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

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

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

于 2019-11-17T11:15:47.310 回答
1

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

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

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

于 2019-11-26T07:32:38.567 回答