Как я могу запустить и дождаться внешнего процесса? - PullRequest
0 голосов
/ 06 марта 2012

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

//When Method1 is called, it will load the data and bring a pop up
//as adobe save dialog box (as a save dialog exe in the task bar)
Method1(); 

while (true)
{
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.Contains("AdobeARM"))
        {
            isOpened = true;
        }
    }  

    //Once the pop up from Method 1 comes i call other methods     
    if (isOpened)
    {
        Method2();
        Method3();
        Method4();
        break;
    }
}

Это может вызвать бесконечный цикл, если процесс не найден!Как лучше всего справиться с этим или альтернативой циклу while?

Ответы [ 5 ]

1 голос
/ 06 марта 2012

Вы говорите: «Я пытаюсь запустить внешний процесс и дождаться его активации, прежде чем продолжить», поэтому я полагаю, что вы используете:

Process prc = new Process(...);
prc.Start();

Если это так, я позвоню

prc.WaitForInputIdle();

, а затем продолжить.
Начиная с MSDN

WaitForInputIdle - Causes the Process component to wait indefinitely for the associated process to enter an idle state. This overload applies only to processes with a user interface and, therefore, a message loop.

1 голос
/ 06 марта 2012

Избавьтесь от времени.

Он выполнит проверку, а затем, если процесс AdobeARM существует, он запустит ваши методы и, если нет, пропустит их.Поместите все сразу после Method1 в отдельную функцию и вызовите эту функцию из System.Threading.Timer.

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

private Timer myTimer;

private void DoSomething()
{
    if (myTimer != null)
    {
        myTimer.Dispose();
        myTimer = null;
    }

    Method1();

    myTimer = new Timer(CheckForProcess, null, 100, 100);
}

private void CheckForProcess(object state)
{
    bool isOpened = false;
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.Contains("AdobeARM"))
        {
            isOpened = true;
            break;
        }
    }

    //Once the pop up from Method 1 comes i call other methods     
    if (isOpened)
    {
        myTimer.Dispose();
        myTimer = null;
        Method2();
        Method3();
        Method4();
    }
}
0 голосов
/ 06 марта 2012

Вместо time (true), попробуйте цикл while, который закончится на основе некоторого значения времени ожидания:

//When Method1 is called, it will load the data and bring a pop up
//as adobe save dialog box (as a save dialog exe in the task bar)
Method1(); 

//define a "timeout" time one minute from now. (or whatever)
var timeout = DateTime.Now.AddSeconds(60);

//loop only while the current time has not exceeded the timeout
while (DateTime.Now < timeout)
{
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.Contains("AdobeARM"))
        {
            isOpened = true;
        }
    }  

    //Once the pop up from Method 1 comes i call other methods     
    if (isOpened)
    {
        Method2();
        Method3();
        Method4();
        break;
    }
    else
        Thread.Yield(); //gives other threads CPU time; Thread.Sleep() works too.
}

//If we exit the loop without isOpened being set, we should probably tell someone.
if(!isOpened) throw new Exception("The operation timed out waiting for AdobeARM.");
0 голосов
/ 06 марта 2012

Использование сна всегда помогает

System.Threading.Thread.Sleep(100); //100ms pause before continuing

Возможно, имеет смысл иметь счетчик или что-то в этом роде, если предположить, что если вы зациклились более 500 раз (50 секунд с этой задержкой),вы не найдете его и должны выйти из цикла.

Пауза также позволит перекрасить ваш экран вместо полной блокировки потока.

0 голосов
/ 06 марта 2012

Может быть просто сломаться?

while (true)
{


           foreach (Process clsProcess in Process.GetProcesses())
           {
                    if (clsProcess.ProcessName.Contains("AdobeARM"))
                    {
                          isOpened = true;
                    }
           }  
           //Once the pop up from Method 1 comes i call other methods                                  
           if (isOpened)
           {
             Method2();
             Method3();
             Method4();
             break;
           }
           else
             break; //BREAK HERE, CAUSE NO PROCESSES of ADOBE...
}

Если вы хотите использовать этот код раз за разом, используйте Timer, но в этом случае, очевидно, не используйте больше while loop.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...