即使使用线程,启动进程也会挂起主进程

发布于 2024-12-28 09:16:38 字数 1669 浏览 3 评论 0原文

我正在尝试运行其他进程,假设来自我的主应用程序 Main.exeChildProcess.exe,并且我希望不会挂起,因为我不想捕获输出,仅shell执行。但不知何故,我的 Main.exe 在某些情况下挂起。两个可执行文件都有 .NET 形式,但此问题发生在尝试访问窗口句柄之前。基本上我所做的就是下面这样。

Main.exe

这就是我为进程执行代码创建一个新线程的方法

...
ThreadStart^ threadStart = gcnew ThreadStart(this, &MyForm::CreateNewProcessThread);
Thread^ thread = gcnew Thread(threadStart);
thread->Start();
...

这里是线程函数

System::Void MyForm::CreateNewProcessThread() {
    String^ ApplicationPath = Application::ExecutablePath->Substring(0, Application::ExecutablePath->LastIndexOf("\\"));
    ...
    Process^ p = gcnew Process();
    p->StartInfo->FileName = ApplicationPath + "\\ChildProcess.exe";
    p->StartInfo->UseShellExecute = true;
    p->StartInfo->RedirectStandardOutput = false;
    p->StartInfo->RedirectStandardError = false;
    p->Start();
    ...
}

ChildProcess 没什么特别的。你可以尝试一下空表格申请,没关系。当我尝试同时运行多个进程时,我的主应用程序开始挂起。它不会像僵局一样永远悬而未决。它只挂起不到 1 秒,但在第一次进程执行时仍然挂起。当 ChildProcess.exe 启动(完全加载)一次后,Main.exe 之后不会受到影响。但是,如果我们对 Form_Load 事件添加一个无限循环,如“while(1);”并尝试同时执行几个进程(例如 3 或 4 个进程),Main.exe 几乎完全被锁定。

这可能是由 STAThread 结构引起的,但由于我使用的是 System.Windows.Forms 命名空间,这看起来是必须的。

我不明白的是,如果我将无限循环放入我的线程(MyForm::CreateNewProcessThread()),我的应用程序根本不会受到这个无限循环的影响,因为它是一个单独的线。但是,当我尝试从该线程启动进程时,包括主线程在内的整个应用程序都会受到影响。

对于这个问题我有两个问题。

1)原因是什么?

2)解决办法是什么?

PS:我在 stackoverflow 上检查了类似的线程,但没有一个提供真正的解释或真正的解决方案。请不要给我其他 stackoverflow 问题的链接。我已经全部检查过了。

I'm trying to run other processes, let's assume ChildProcess.exe, from my main application Main.exe and I expect no hanging since I'm not trying to catch the output, only shell execute. But somehow, my Main.exe hangs in some conditions. Both executables have .NET forms but this problem occurs before trying to reach window handles. Basicly what I do is something like below.

Main.exe

This is how I create a new thread for process executing code

...
ThreadStart^ threadStart = gcnew ThreadStart(this, &MyForm::CreateNewProcessThread);
Thread^ thread = gcnew Thread(threadStart);
thread->Start();
...

Here is the thread function

System::Void MyForm::CreateNewProcessThread() {
    String^ ApplicationPath = Application::ExecutablePath->Substring(0, Application::ExecutablePath->LastIndexOf("\\"));
    ...
    Process^ p = gcnew Process();
    p->StartInfo->FileName = ApplicationPath + "\\ChildProcess.exe";
    p->StartInfo->UseShellExecute = true;
    p->StartInfo->RedirectStandardOutput = false;
    p->StartInfo->RedirectStandardError = false;
    p->Start();
    ...
}

ChildProcess is nothing special. You can try an empty form application, it doesn't matter. When I try to run multiple processes at the same time, my main application starts hanging. It doesn't hang forever like a deadlock. It just hangs for less than 1 seconds but it still hangs at the first process execution. When ChildProcess.exe is started (completely loaded) once, Main.exe is not affected afterwards. But if we put an infinite loop to the Form_Load event like "while(1);" and try to execute a few processes at the same time (like 3 or 4 nothing more), Main.exe is almost completely locked up.

This might be caused by the STAThread structure but since I'm using System.Windows.Forms namespace, this looks like a must.

What I don't get it is, if I put and infinite loop to my thread (MyForm::CreateNewProcessThread()), my application is not affected by this infinite loop at all since it is a seperate thread. But when I try to start a process from that thread, my whole application including my main thread is affected.

I have two questions on this problem.

1) What is the reason?

2) What is the solution?

P.S: I checked similar threads on stackoverflow and none of them provided a real explanation or real solution. Please don't give me links the other stackoverflow questions. I've already checked them all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

厌倦 2025-01-04 09:16:38

我找不到“托管”方法来解决我的问题。所以我使用了Win32 API(CreateProcess()FindWindow()WaitForInputIdle()EnumThreadWindows()等.)。现在它可以正常工作而不会挂起,但我仍然不知道 .NET 的 Process 类出了什么问题。

I couldn't find a "managed" way to solve my problem. So I used Win32 API (CreateProcess(), FindWindow(), WaitForInputIdle(), EnumThreadWindows() etc.). Now it's working without hanging but I still don't know what's wrong with .NET's Process class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文