in

C process waitforexit

Process. Wait For Exit Process. Wait For Exit Process. Wait For Exit Process. Wait For Exit Method

Определение

Задает период времени для ожидания завершения связанного процесса и блокирует текущий поток выполнения до того, как пройдет это время или процесс завершится. Sets the period of time to wait for the associated process to exit, and blocks the current thread of execution until the time has elapsed or the process has exited. Чтобы избежать блокировки текущего потока, используйте событие Exited. To avoid blocking the current thread, use the Exited event. Примеры кода см. на следующих страницах справочника по свойствам StandardError и ExitCode. For code examples, see the StandardError and the ExitCode property reference pages.

В этой статье

Перегрузки

Дает компоненту Process команду ожидать завершения связанного процесса в течение неограниченного времени. Instructs the Process component to wait indefinitely for the associated process to exit.

Дает компоненту Process команду ожидать завершения связанного процесса в течение указанного времени в миллисекундах. Instructs the Process component to wait the specified number of milliseconds for the associated process to exit.

WaitForExit() WaitForExit() WaitForExit() WaitForExit()

Дает компоненту Process команду ожидать завершения связанного процесса в течение неограниченного времени. Instructs the Process component to wait indefinitely for the associated process to exit.

Исключения

Нет доступа к параметру ожидания. The wait setting could not be accessed.

Не задан Id процесса, и Handle, из которого можно определить свойство Id, не существует. No process Id has been set, and a Handle from which the Id property can be determined does not exist. — или — -or- С этим объектом Process никакие процессы не связаны. There is no process associated with this Process object. — или — -or- Вы пытаетесь вызвать метод WaitForExit() для процесса, выполняющегося на удаленном компьютере. You are attempting to call WaitForExit() for a process that is running on a remote computer. Этот метод доступен только для процессов, запущенных на локальном компьютере. This method is available only for processes that are running on the local computer.

Примеры

См. в разделе «Примечания» StandardError справочной странице. See the Remarks section of the StandardError property reference page.

Комментарии

WaitForExit() делает текущий поток ждал до завершения связанного процесса. WaitForExit() makes the current thread wait until the associated process terminates. Его следует вызывать после вызова всех остальных методов для процесса. It should be called after all other methods are called on the process. Чтобы избежать блокировки текущего потока, используйте событие Exited. To avoid blocking the current thread, use the Exited event.

Указывает, что этот метод Process ожидания неограниченного количества времени для процесса и обработчики событий для выхода. This method instructs the Process component to wait an infinite amount of time for the process and event handlers to exit. Это может вызвать приложение перестает отвечать на запросы. This can cause an application to stop responding. Например, если вы вызываете CloseMainWindow для процесса, который имеет пользовательский интерфейс, запрос к операционной системе на завершение процесса может быть не обработан, если запись процесса не нужно вводить его цикл обработки сообщений. For example, if you call CloseMainWindow for a process that has a user interface, the request to the operating system to terminate the associated process might not be handled if the process is written to never enter its message loop.

В .NET Framework 3,5 .NET Framework 3.5 и более ранних версий WaitForExit() ожидание перегрузки MaxValue миллисекунд (приблизительно 24 дней), не бесконечно. In the .NET Framework 3,5 .NET Framework 3.5 and earlier versions, the WaitForExit() overload waited for MaxValue milliseconds (approximately 24 days), not indefinitely. Кроме того, предыдущие версии были ожидает обработчики событий выход в случае полной MaxValue достигнуто время. Also, previous versions did not wait for the event handlers to exit if the full MaxValue time was reached.

Эта перегрузка гарантирует, что вся обработка завершения, включая обработку асинхронных событий для перенаправленного стандартного вывода. This overload ensures that all processing has been completed, including the handling of asynchronous events for redirected standard output. Эту перегрузку следует использовать после вызова WaitForExit(Int32) перегрузки, когда был перенаправлен стандартный поток вывода для асинхронных обработчиков событий. You should use this overload after a call to the WaitForExit(Int32) overload when standard output has been redirected to asynchronous event handlers.

При завершении связанного процесса (то есть, когда его работа была завершена функцией операционной системы через нормальное или аварийное завершение), система сохраняет административную информацию о процессе и возвращает к компоненту, вызвавшему метод WaitForExit(). When an associated process exits (that is, when it is shut down by the operation system through a normal or abnormal termination), the system stores administrative information about the process and returns to the component that had called WaitForExit(). Process Может получить доступ к сведения, а также ExitTime, с помощью Handle завершенных процессов. The Process component can then access the information, which includes the ExitTime, by using the Handle to the exited process.

Так как связанный процесс завершился, Handle свойства компонента больше не указывает на существующий ресурс процесса. Because the associated process has exited, the Handle property of the component no longer points to an existing process resource. Вместо этого дескриптор может использоваться только для доступа к операционной системы сведения о ресурсе процесса. Instead, the handle can be used only to access the operating system’s information about the process resource. Система известно о дескрипторах завершенных процессов, которые не были освобождены Process компонентов, поэтому она хранит ExitTime и Handle информацию в памяти до Process компонента, в частности, освобождает ресурсы. The system is aware of handles to exited processes that have not been released by Process components, so it keeps the ExitTime and Handle information in memory until the Process component specifically frees the resources. По этой причине при каждом вызове Start для Process экземпляра, вызовите Close при связанный процесс был завершен, и больше не нужны административной информации о нем. For this reason, any time you call Start for a Process instance, call Close when the associated process has terminated and you no longer need any administrative information about it. Close Освобождает память, выделенную завершенных процессов. Close frees the memory allocated to the exited process.

Безопасность

LinkDemand
для полного доверия для непосредственного вызывающего объекта. for full trust for the immediate caller. Этот член не может быть использован частично доверенным кодом. This member cannot be used by partially trusted code.

WaitForExit(Int32) WaitForExit(Int32) WaitForExit(Int32) WaitForExit(Int32)

Дает компоненту Process команду ожидать завершения связанного процесса в течение указанного времени в миллисекундах. Instructs the Process component to wait the specified number of milliseconds for the associated process to exit.

Параметры

Количество времени в миллисекундах для ожидания завершения связанного процесса. The amount of time, in milliseconds, to wait for the associated process to exit. Максимальным является наибольшее возможное 32-битное целое число, которое представляет для операционной системы бесконечность. The maximum is the largest possible value of a 32-bit integer, which represents infinity to the operating system.

Возвраты

Значение true , если связанный процесс завершился; в противном случае — значение false . true if the associated process has exited; otherwise, false .

Исключения

Нет доступа к параметру ожидания. The wait setting could not be accessed.

Не задан Id процесса, и Handle, из которого можно определить свойство Id, не существует. No process Id has been set, and a Handle from which the Id property can be determined does not exist. — или — -or- С этим объектом Process никакие процессы не связаны. There is no process associated with this Process object. — или — -or- Вы пытаетесь вызвать метод WaitForExit(Int32) для процесса, выполняющегося на удаленном компьютере. You are attempting to call WaitForExit(Int32) for a process that is running on a remote computer. Этот метод доступен только для процессов, запущенных на локальном компьютере. This method is available only for processes that are running on the local computer.

Параметр milliseconds является отрицательным числом, отличным от –1, что означает бесконечное время ожидания. milliseconds is a negative number other than -1, which represents an infinite time-out.

Примеры

См. в примере кода ExitCode свойство. See the code example for the ExitCode property.

Комментарии

WaitForExit(Int32) делает текущий поток ждал до завершения связанного процесса. WaitForExit(Int32) makes the current thread wait until the associated process terminates. Его следует вызывать после вызова всех остальных методов для процесса. It should be called after all other methods are called on the process. Чтобы избежать блокировки текущего потока, используйте событие Exited. To avoid blocking the current thread, use the Exited event.

Указывает, что этот метод Process ожидания конечное количество времени для завершения процесса. This method instructs the Process component to wait a finite amount of time for the process to exit. Если связанный процесс не завершится по истечении интервала из-за отказа в запросе на завершение false возвращается вызвавшей процедуре. If the associated process does not exit by the end of the interval because the request to terminate is denied, false is returned to the calling procedure. Можно указать Timeout.Infinite для milliseconds , и Process.WaitForExit(Int32) будет вести себя так же, как WaitForExit() перегрузки. You can specify Timeout.Infinite for milliseconds , and Process.WaitForExit(Int32) will behave the same as the WaitForExit() overload. Если методу передается 0 (ноль), он возвращает true только в том случае, если процесс уже завершился; в противном случае он немедленно возвращает false . If you pass 0 (zero) to the method, it returns true only if the process has already exited; otherwise, it immediately returns false .

В .NET Framework 3,5 .NET Framework 3.5 и более ранних версий, если milliseconds -1, WaitForExit(Int32) ожидание перегрузки MaxValue миллисекунд (приблизительно 24 дней), не бесконечно. In the .NET Framework 3,5 .NET Framework 3.5 and earlier versions, if milliseconds was -1, the WaitForExit(Int32) overload waited for MaxValue milliseconds (approximately 24 days), not indefinitely.

Когда стандартный вывод был перенаправлен к асинхронных обработчиков событий, вполне возможно, что обработка вывода не будет завершена при возвращении данного метода. When standard output has been redirected to asynchronous event handlers, it is possible that output processing will not have completed when this method returns. Чтобы гарантировать завершение асинхронной обработки событий, вызвать WaitForExit() перегрузку, принимающую параметр не после получения true из этой перегрузки. To ensure that asynchronous event handling has been completed, call the WaitForExit() overload that takes no parameter after receiving a true from this overload. Чтобы обеспечить Exited правильную обработку событий в приложениях Windows Forms, задайте SynchronizingObject свойство. To help ensure that the Exited event is handled correctly in Windows Forms applications, set the SynchronizingObject property.

При завершении связанного процесса (завершает работу операционной системой через обычный или аварийное завершение), система сохраняет административную информацию о процессе и возвращает к компоненту, вызвавшему метод WaitForExit(Int32). When an associated process exits (is shut down by the operating system through a normal or abnormal termination), the system stores administrative information about the process and returns to the component that had called WaitForExit(Int32). Process Может получить доступ к сведения, а также ExitTime, с помощью Handle завершенных процессов. The Process component can then access the information, which includes the ExitTime, by using the Handle to the exited process.

Так как связанный процесс завершился, Handle свойства компонента больше не указывает на существующий ресурс процесса. Because the associated process has exited, the Handle property of the component no longer points to an existing process resource. Вместо этого дескриптор может использоваться только для доступа к операционной системы сведения о ресурсе процесса. Instead, the handle can be used only to access the operating system’s information about the process resource. Система известно о дескрипторах завершенных процессов, которые не были освобождены Process компонентов, поэтому она хранит ExitTime и Handle информацию в памяти до Process компонента, в частности, освобождает ресурсы. The system is aware of handles to exited processes that have not been released by Process components, so it keeps the ExitTime and Handle information in memory until the Process component specifically frees the resources. По этой причине при каждом вызове Start для Process экземпляра, вызовите Close при связанный процесс был завершен, и больше не нужны административной информации о нем. For this reason, any time you call Start for a Process instance, call Close when the associated process has terminated and you no longer need any administrative information about it. Close Освобождает память, выделенную завершенных процессов. Close frees the memory allocated to the exited process.

Безопасность

LinkDemand
для полного доверия для непосредственного вызывающего объекта. for full trust for the immediate caller. Этот член не может быть использован частично доверенным кодом. This member cannot be used by partially trusted code.

c# — ProcessStartInfo висит на «WaitForExit»? Зачем?

У меня есть следующий код:

Я знаю, что результат процесса, который я запускаю, составляет около 7 МБ. Запуск его в консоли Windows отлично работает. К сожалению, программно это бесконечно зависает в WaitForExit. Обратите внимание, что это также делает код НЕ зависает для меньших выходов (например, 3 КБ).

Возможно ли, что внутренняя функция StandardOutput в ProcessStartInfo не может буферизовать 7 МБ? Если да, то что мне делать вместо этого? Если нет, что я делаю неправильно?

Answers

Проблема в том, что если вы перенаправляете StandardOutput и / или StandardError внутренний буфер может стать полным. Какой бы порядок вы ни использовали, может возникнуть проблема:

  • Если вы дождались завершения процесса перед чтением StandardOutput процесс может блокировать попытку записи на него, поэтому процесс никогда не заканчивается.
  • Если вы прочитали из StandardOutput с помощью ReadToEnd, то ваш процесс может блокироваться, если процесс никогда не закрывает StandardOutput (например, если он никогда не завершается или блокируется при записи в StandardError ).

Решение заключается в использовании асинхронных чтений, чтобы гарантировать, что буфер не будет заполнен. Чтобы избежать каких-либо взаимоблокировок и собирать все данные как из StandardOutput и из StandardError вы можете сделать это:

EDIT: см. Ответы ниже, как избежать исключения ObjectDisposedException, если происходит таймаут.

Ответ Mark Byers превосходный, но я бы просто добавил следующее: делегаты OutputDataReceived и ErrorDataReceived должны быть удалены до того, как будут удалены функции outputWaitHandle и errorWaitHandle. Если процесс продолжает выводить данные после того, как таймаут был превышен, а затем завершается, после выхода будут доступны переменные outputWaitHandle и errorWaitHandle.

(FYI мне пришлось добавить это оговорку в качестве ответа, поскольку я не мог прокомментировать его сообщение).

Роб ответил на это и спас мне несколько часов испытаний. Прочитайте буфер вывода / ошибки перед ожиданием:

Обратите внимание на решение Mark Byers :

Я решил это так:

Я перенаправлял как входные, так и выходные данные, а также обрабатывал чтение с потоком вывода и ошибок. Это решение работает для SDK 7-8.1, как для Windows 7, так и для Windows 8

Ни один из вышеперечисленных ответов не выполняет эту работу.

Решение Rob зависает, и решение «Mark Byers» получает исключение. (Я попробовал «решения» других ответов).

Поэтому я решил предложить другое решение:

Этот код отлаживается и работает отлично.

Я знаю, что это ужин старый, но после прочтения всей этой страницы ни один из решений не работал для меня, хотя я не пытался Мухаммада Рехана, поскольку код был немного трудно следовать, хотя, я думаю, он был на правильном пути , Когда я говорю, что это не сработало, это не совсем так, иногда это будет нормально работать, я думаю, что это связано с длиной выхода до отметки EOF.

Во всяком случае, решение, которое работало для меня, состояло в том, чтобы использовать разные потоки для чтения StandardOutput и StandardError и писать сообщения.

Надеюсь, это поможет кому-то, кто думал, что это может быть так сложно!

Это сообщение может быть устаревшим, но я узнал основную причину, почему он обычно зависает из-за переполнения стека для redirectStandardoutput или если у вас есть redirectStandarderror.

Поскольку выходные данные или данные об ошибках являются большими, это вызовет время зависания, поскольку оно все еще обрабатывается на неопределенный срок.

поэтому для решения этой проблемы:

У меня была такая же проблема, но причина была другая. Однако это произойдет в Windows 8, но не под Windows 7. Кажется, что эта проблема вызвала следующую строку.

Решение состояло в том, чтобы НЕ отключить UseShellExecute. Теперь я получил всплывающее окно Shell, которое нежелательно, но намного лучше, чем программа, ожидающая ничего особенного. Поэтому я добавил для этого следующую работу:

Теперь меня беспокоит только то, почему это происходит в Windows 8 в первую очередь.

Вопрос: Process.WaitForExit несовместим на разных машинах

Этот код работает, как ожидалось, на большом количестве машин. Однако на одной конкретной машине вызов WaitForExit() кажется, игнорируется, и фактически отмечает, что процесс завершен.

Обратите внимание, что в отличие от аналогичный вопрос на SO, процесс, называемый notepad.exe (по причинам тестирования), так что маловероятно, что с ним возникла ошибка, то есть он не порождает второй подпроцесс и закрывается. Тем не менее, это не объяснит, почему он работает на всех других машинах.

На проблемной машине второй вызов Console.WriteLine(proc.HasExited)) возвращается true хотя блокнот все еще четко открыт, как на экране, так и в диспетчере задач.

Машина работает под управлением Windows 7 и .NET 4.0.

Мой вопрос: какие условия на этой конкретной машине могут быть причиной этого? Что я должен проверять?

Изменить — все, что я пробовал до сих пор / Обновления / Возможно релевантная информация:

  • Переустановил .NET.
  • Закрыто любые процессы, которые я не знаю в диспетчере задач.
  • Windows еще не активирована на этом компьютере.
  • Следуя советам в комментариях, я попытался использовать «существующий» идентификатор процесса, используя GetProcessesByName но это просто возвращает пустой массив на проблемную машину. Поэтому трудно сказать, что проблема даже с WaitForExit , поскольку процесс не возвращается путем вызова GetProcessesByName даже до звонка WaitForExit ,
  • На проблемной машине полученный ParentID процесса в блокноте — это идентификатор процесса блокнота, который запускается вручную, или, другими словами, блокнот порождает дочерний процесс и завершает сам.

Ответы:

Проблема в том, что по умолчанию для параметра Process.StartInfo.UseShellExecute установлено значение true. Если эта переменная установлена ​​в true, а не запускает процесс самостоятельно, вы просите оболочку запустить ее для вас. Это может быть весьма полезно — это позволяет вам делать такие вещи, как «выполнить» HTML-файл (оболочка будет использовать соответствующее приложение по умолчанию).

Это не так хорошо, когда вы хотите отслеживать приложение после его выполнения (как вы нашли), потому что приложение-запуск иногда может запутаться в том, какой экземпляр он должен отслеживать.

Внутренние детали здесь, почему это происходит, вероятно, превосходят мои возможности для ответа — я знаю, что когда UseShellExecute == true, среда использует ShellExecuteEx Windows API, а когда она UseShellExecute == false, она использует CreateProcessWithLogonW, но почему одна ведет для отслеживаемых процессов, а другой — я не знаю, поскольку оба они возвращают идентификатор процесса.

EDIT: После небольшого рытья:

Этот вопрос указал мне на SEE_MASK_NOCLOSEPROCESS флаг, который действительно кажется установленным при использовании ShellExecute. Документация для значения маски:

В некоторых случаях, например, когда выполнение выполняется через DDE разговор, никакой дескриптор не будет возвращен. Вызывающее приложение ответственный за закрытие ручки, когда она больше не нужна.

Поэтому он предполагает, что возврат дескриптора процесса ненадежен. Я до сих пор не получил достаточно глубоких знаний, чтобы узнать, какой конкретный случай, который вы могли бы нанести здесь.

C process waitforexit

I use Process.Start to start a batch file. The batch file uses the «START» command to start several programs in parallel and then exits.

Once the batch file is done Process.HasExited becomes true and Process.ExitCode contains the correct exit code.

But when I call Process.WaitForExit() it hangs / never returns.

The following piece of code demonstrates the problem. It creates a batch file, starts it and then prints:

It should then print:

. but it never does (even though HasExited is true and we already have an ExitCode).

I noticed that this only happens when the batch file contains «START» commands and when standard output and/or standard error are redirected.

Why does WaitForExit() never return?

What’s the right way to wait for such a process to exit?

Is it safe to just poll Process.HasExited or can that result in other problems?

PS.: I just noticed that calling WaitForExit(100000) with a huge timeout (that definitely doesn’t expire) returns immediately when the process exits. Wierd. Without timeout it hangs.

1 Answer

This seems to be an artifact (I’d say «bug») in the specific implementation of the event-based asynchronous handling of StandardOutput and StandardError.

I noticed that while I was able to easily reproduce your problem, simply by running the code you provided (excellent code example, by the way! 🙂 ), the process did not actually hang indefinitely. Rather, it returned from WaitForExit() once both of the child processes that had been started had themselves exited.

This seems to be an intentional part of the implementation of the Process class. In particular, in the Process.WaitForExit() method, once it has finished waiting on the process handle itself, it checks to see if a reader for either stdout or stderr has been created; if so, and if the timeout value for the WaitForExit() call is «infinite» (i.e. -1 ), the code actually waits for the end-of-stream on the reader(s).

Each respective reader is created only when the BeginOutputReadLine() or BeginErrorReadLine() method is called. The stdout and stderr streams are themselves not closed until the child processes have closed. So waiting on the end of those streams will block until that happens.

That WaitForExit() should behave differently depending on whether one has called either of the methods that start the event-based reading of the streams or not, and especially given that reading those streams directly does not cause WaitForExit() to behave that way, creates an inconsistency in the API that makes it much more difficult to understand and use. While I’d personally call this a bug, I suppose it’s possible that the implementor(s) of the Process class are aware of this inconsistency and created it on purpose.

In any case, the work-around would be to read StandardOutput and StandardError directly instead of using the event-based part of the API. (Though of course, if one’s code were to wait on those streams, one would see the same blocking behavior until the child processes close.)

For example (C#, because I don’t know F# well enough to slap a code example like this together quickly 🙂 ):

Hopefully the above work-around or something similar will address the basic issue you’ve run into. My thanks to commenter Niels Vorgaard Christensen for directing me to the problematic lines in the WaitForExit() method, so that I could improve this answer.

Как использовать класс Process в .NET Framework

Версия 1.4 (обновлено 9 ноября 2008 г.)

Иногда программисту требуется запустить другое приложение из своей программы. Для этой цели подойдет метод Start класса Process из пространства имен System.Diagnostics. Как и многие другие методы в .NET, метод Start имеет несколько перегруженных версий. Вам нужно лишь выбрать наиболее подходящий вариант для выполнения ваших задач.

Запуск документа в сопоставленной программе

Если вы хотите показать текстовый файл в Блокноте, то просто напишите:

Учтите, что файл readme.txt должен находиться в той же папке, что и вызывающее приложение. Программа Блокнот должна быть программой по умолчанию для текстовых файлов для первого случая (или у вас запустится другой текстовый редактор). Во втором случае Блокнот (notepad.exe) должен быть прописан в переменной среды. Если вы раньше программировали на VB6, то Process.Start напомнит вам команду Shell:

Вы можете использовать команду Shell и в VB.NET, но делать этого совсем не стоит.

Запуск браузера по умолчанию

Если вам нужно запустить браузер по умолчанию по заданной ссылке, то используйте следующий код:

Создание и отправка письма

Существует очень легкий и быстрый способ создания и отправки письма с использованием технологии, применяемой на веб-страницах. С помощью ключевого слова mailto создается заготовка письма, в которой указывается автор сообщения, тема и текст письма. После этого запускается процесс, который в автоматическом режиме запускает нужную почтовую программу и отсылает письмо.

Если вы хотите большей гибкости при запуске другого приложения, то создайте объект ProcessStartInfo, с помощью которого сможете управлять поведением программы.

Если вам необходим запуск приложения с запретом на закрытие своего приложения (В VB6 пришлось бы использовать кучу вызовов Windows API), то используйте метод WaitForExit.

C помощью класса Process можно не только запускать приложения, но и закрывать их при помощи метода Kill.

Обратите внимание, что на панели инструментов появился компонент Process, который вы можете добавить в свой проект и выполнить многие задачи еще на этапе разработки, а не во время выполнения программы.

Свернуть все программы Блокнот

С помощью метода Process.GetProcessesByName можно получить список всех запущенных экземпляров Notepad.exe и применить к ним какие-нибудь действия. Например, мы хотим свернуть все запущенные программы Блокнот.

В приведенном примере сначала получаем список запущенных процессов Notepad, а затем при помощи функций Windows API сворачиваем все обнаруженные окна Блокнота.

Незаметный» запуск внешних процессов

Иногда возникает необходимость запустить внешний процесс, получить от него какие-либо данные (либо просто дать ему возможность отработать) и затем его закрыть. Однако внешний процесс становится виден пользователю (часто это можно наблюдать при работе инсталляторов). А вот чтобы запустить внешний процесс незаметно для пользователя, надо в классе настроек запуска процесса ProcessStartInfo свойству WindowStyle присвоить значение ProcessWindowStyle.Hidden.

Например, вы можете запустить Блокнот как скрытый процесс:

Но в этом случае нужно быть осторожным, так как неправильное использование этой возможности может привести к печальным последствиям.

Ниже представлен небольшой пример «незаметного» запуска процессов, который запускает утилиту Reg.exe и делает бэкап ветки реестра HKEY_CLASSES_ROOT\mailto в файл.

Повышение уровня привилегий в Windows Vista

Чтобы повысить уровень привилегий в Windows Vista через системное диалоговое окно UAC, используйте следующее:

В приведенном примере показано, как можно запускать новый процесс с повышенными привилегиями.

ProcessStartInfo hanging on “WaitForExit”? Why?

I have the following code:

I know that the output from the process I am starting is around 7MB long. Running it in the Windows console works fine. Unfortunately programmatically this hangs indefinitely at WaitForExit. Note also this does code NOT hang for smaller outputs (like 3KB).

Is it possible that the internal StandardOutput in ProcessStartInfo can’t buffer 7MB? If so, what should I do instead? If not, what am I doing wrong?

Handle large amounts of output from p.WaitForExit() with RedirectStandardOutput = True

As discussed here ProcessStartInfo hanging on WaitForExit? Why? – calling p.WaitForExit() with a large output fills the OutputStream and causes a deadlock as the process and the output stream wait f

ProcessStartInfo .WaitForExit() is not working properly

So, I have this code to call a batch file. If System.IO.File.Exists(FSourceFile) Then Dim psi As New ProcessStartInfo(batchFileLoc + batchFileName) psi.RedirectStandardOutput = True psi.WindowStyle =

why Process.WaitForExit doesn’t wait?

Why is the WaitForExit not an available method in my C# code?

The code below works fine but I need to add the WaitForExit method. But it doesn’t show as being available. What am I missing? Thanks. ProcessStartInfo process = new ProcessStartInfo(cmd.exe, @/C

why WaitForExit() doesn’t wait?

i am adding Custom Action into my VS2008 setup project (MSI installer). I am calling a batch file to create database and want to delete those files after. I have WaitForExit() but it will not wait. Wh

Why does Process.Start(ProcessStartInfo) fail?

We’ve developed a new WPF application, and I have had difficulty launching it from external C# script. While calling Process.Start(ProcessStartInfo) method with ProcessStartInfo object which is initia

c# ProcessStartInfo

Why is this ProcessStartInfo myProcess = new ProcessStartInfo(path); myProcess.UserName = username; myProcess.Password = MakeSecureString(password); myProcess.UseShellExecute = false; Process.Start(my

Why is my MailboxProcessor hanging?

I can’t work out why the following code is hanging at the call to GetTotal. I don’t seem to be able to debug inside the MailboxProcessor, so it’s hard to see what’s going on. module Aggregator open Sy

Process WaitForExit()

I use the below statements in my application: System.Diagnostics.Process process = new System.Diagnostics.Process(); process.StartInfo.FileName = ‘FileName’; process.Start(); process.WaitForExit(90000

Why would Process.WaitForExit throw a “no process” exception even when a process does exist?

I have a windows service containing this code: public static void ExtractTextInner(string source, string destination) < ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = EXTRA

Answers

The documentation for Process.StandardOutput says to read before you wait otherwise you can deadlock, snippet copied below:

We have this issue as well (or a variant).

Try the following:

1) Add a timeout to p.WaitForExit(nnnn); where nnnn is in milliseconds.

2) Put the ReadToEnd call before the WaitForExit call. This is what we’ve seen MS recommend.

This post maybe outdated but i found out the main cause why it usually hang is due to stack overflow for the redirectStandardoutput or if you have redirectStandarderror.

As the output data or the error data is large, it will cause a hang time as it is still processing for indefinite duration.

so to resolve this issue:

The problem is that if you redirect StandardOutput and/or StandardError the internal buffer can become full. Whatever order you use, there can be a problem:

  • If you wait for the process to exit before reading StandardOutput the process can block trying to write to it, so the process never ends.
  • If you read from StandardOutput using ReadToEnd then your process can block if the process never closes StandardOutput (for example if it never terminates, or if it is blocked writing to StandardError).

The solution is to use asynchronous reads to ensure that the buffer doesn’t get full. To avoid any deadlocks and collect up all output from both StandardOutput and StandardError you can do this:

Mark Byers’ answer is excellent, but I would just add the following: the OutputDataReceived and ErrorDataReceived delegates need to be removed before the outputWaitHandle and errorWaitHandle get disposed. If the process continues to output data after the timeout has been exceeded and then terminates, the outputWaitHandle and errorWaitHandle variables will be accessed after being disposed.

(FYI I had to add this caveat as an answer as I couldn’t comment on his post.)

I thing that this is simple and better approach (we don’t need AutoResetEvent):

Ваше мнение о статье

0 points
Upvote Downvote

Total votes: 0

Upvotes: 0

Upvotes percentage: 0.000000%

Downvotes: 0

Downvotes percentage: 0.000000%

Добавить комментарий

График форекс с объемами продаж онлайн

Робофорекс вход в кабинет