При запуске процесса основной процесс зависает даже при использовании потоков - PullRequest
0 голосов
/ 19 января 2012

Я пытаюсь запустить другие процессы, допустим, ChildProcess.exe, из моего основного приложения Main.exe, и я не ожидаю зависания, так как я не пытаюсь перехватить вывод, только выполнение оболочки.Но почему-то мой 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.Я уже проверил их все.

1 Ответ

1 голос
/ 20 января 2012

Мне не удалось найти «управляемый» способ решения моей проблемы.Поэтому я использовал Win32 API (CreateProcess(), FindWindow(), WaitForInputIdle(), EnumThreadWindows() и т. Д.).Теперь он работает без зависаний, но я все еще не знаю, что не так с классом .NET Process.

...