Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. External process stops everything else

External process stops everything else

Scheduled Pinned Locked Moved .NET (Core and Framework)
winformsdebuggingquestion
9 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    piul
    wrote on last edited by
    #1

    I have a windows Forms application that calls a mathematical calculations .exe

    		superMinerProcess->Start();
    		superMinerProcess->BeginOutputReadLine();	//Start reading the output
    		while (!superMinerProcess->HasExited)
    		{    //...   }
    

    If I set a breakpoint after the Start(); the program only reaches it after the process has finished. I don't understand... Any idea?

    L 1 Reply Last reply
    0
    • P piul

      I have a windows Forms application that calls a mathematical calculations .exe

      		superMinerProcess->Start();
      		superMinerProcess->BeginOutputReadLine();	//Start reading the output
      		while (!superMinerProcess->HasExited)
      		{    //...   }
      

      If I set a breakpoint after the Start(); the program only reaches it after the process has finished. I don't understand... Any idea?

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      That is inconclusive. Where is this code located? what is in the while loop? what is it you are trying to achieve? :)

      Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

      Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

      P 1 Reply Last reply
      0
      • L Luc Pattyn

        That is inconclusive. Where is this code located? what is in the while loop? what is it you are trying to achieve? :)

        Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

        Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

        P Offline
        P Offline
        piul
        wrote on last edited by
        #3

        The application is a dialog that runs a long mathematical calculation (the external process, an independent executable) when pressing a Run button. Hence, this code is located within the buttonRun_Click function.

        while (!superMinerProcess->HasExited)
        {
        if (processCancelled)
        {
        processCancelled = false;
        break;
        }
        }

        processCancelled is set to true in buttonCancel_Click. What I´m trying is to be able to kill the process when the user clicks on the Cancel button. I´ve tried writing superMinerProcess->Kill() in buttonCancel_Click but it won´t work because the Cancel button is just not clickable while the process is running. Here´s the rest of relevant code of the process

        superMinerProcess = gcnew System::Diagnostics::Process;
        superMinerProcess->StartInfo = gcnew System::Diagnostics::ProcessStartInfo;
        superMinerProcess->StartInfo->RedirectStandardOutput = true;
        superMinerProcess->StartInfo->UseShellExecute = false; //Necessary to redirect
        superMinerProcess->StartInfo->FileName = SUPERMINER_EXE;
        superMinerProcess->StartInfo->CreateNoWindow = true; //Don't open a new window for Process
        //Arguments
        superMinerProcess->StartInfo->Arguments = getArguments();
        superMinerProcess->OutputDataReceived += gcnew System::Diagnostics::DataReceivedEventHandler (&Form1::StdoutHandler);

        L 1 Reply Last reply
        0
        • P piul

          The application is a dialog that runs a long mathematical calculation (the external process, an independent executable) when pressing a Run button. Hence, this code is located within the buttonRun_Click function.

          while (!superMinerProcess->HasExited)
          {
          if (processCancelled)
          {
          processCancelled = false;
          break;
          }
          }

          processCancelled is set to true in buttonCancel_Click. What I´m trying is to be able to kill the process when the user clicks on the Cancel button. I´ve tried writing superMinerProcess->Kill() in buttonCancel_Click but it won´t work because the Cancel button is just not clickable while the process is running. Here´s the rest of relevant code of the process

          superMinerProcess = gcnew System::Diagnostics::Process;
          superMinerProcess->StartInfo = gcnew System::Diagnostics::ProcessStartInfo;
          superMinerProcess->StartInfo->RedirectStandardOutput = true;
          superMinerProcess->StartInfo->UseShellExecute = false; //Necessary to redirect
          superMinerProcess->StartInfo->FileName = SUPERMINER_EXE;
          superMinerProcess->StartInfo->CreateNoWindow = true; //Don't open a new window for Process
          //Arguments
          superMinerProcess->StartInfo->Arguments = getArguments();
          superMinerProcess->OutputDataReceived += gcnew System::Diagnostics::DataReceivedEventHandler (&Form1::StdoutHandler);

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          OK, that is quite wrong for several reasons: 1. the while loop has no blocking calls, so it will spin at full speed, consuming all cycles of one (perhaps the only) core. If you must have a polling loop like that, at least slow it down by inserting say Thread.Sleep(100); However it is in general better to avoid a polling loop. 2. It is not OK to halt the main thread like that, as the whole GUI will freeze. If e.g. another window pops up on top of your app, and then goes away again, your app won't repaint itself. The correct approach would be: - to have a separate thread (I suggest a BackgroundWorker) which launches the process, captures its output, and waits for its termination; - to launch this thread from your button click handler (possibly also disabling said button, turning the cursor into a wait cursor, etc); - to have a delegate dealing with intermediate results (maybe showing them in a ListBox); - to have another delegate dealing with the termination of the process (restoring the GUI back to normal). BTW: said thread would not need a polling loop on superMinerProcess->HasExited, as it could use superMinerProcess->WaitForExit() :)

          Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

          Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

          P 1 Reply Last reply
          0
          • L Luc Pattyn

            OK, that is quite wrong for several reasons: 1. the while loop has no blocking calls, so it will spin at full speed, consuming all cycles of one (perhaps the only) core. If you must have a polling loop like that, at least slow it down by inserting say Thread.Sleep(100); However it is in general better to avoid a polling loop. 2. It is not OK to halt the main thread like that, as the whole GUI will freeze. If e.g. another window pops up on top of your app, and then goes away again, your app won't repaint itself. The correct approach would be: - to have a separate thread (I suggest a BackgroundWorker) which launches the process, captures its output, and waits for its termination; - to launch this thread from your button click handler (possibly also disabling said button, turning the cursor into a wait cursor, etc); - to have a delegate dealing with intermediate results (maybe showing them in a ListBox); - to have another delegate dealing with the termination of the process (restoring the GUI back to normal). BTW: said thread would not need a polling loop on superMinerProcess->HasExited, as it could use superMinerProcess->WaitForExit() :)

            Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

            Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

            P Offline
            P Offline
            piul
            wrote on last edited by
            #5

            I like the idea of having the process in a different thread. It does work much better. However I have a problem when it comes to display in my form the text captured from the process. I have a delegate superMinerThreadWorkCompleted in charge of displaying the results.

            void superMinerThreadWorkCompleted (System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e)
            {
            textBox = "Process text";
            }

            But I get the error C3352: superMinerThreadWorkCompleted(System::Object ^,System::ComponentModel::DoWorkEventArgs ^)' : the specified function does not match the delegate type 'void (System::Object ^,System::ComponentModel::RunWorkerCompletedEventArgs ^)' 1>Form1.cpp in the line

            superMinerThread->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler (&Form1::superMinerThreadWorkCompleted);

            I can fix this by making the delegate static but then I cannot modify member class textBox. What could be the way around this?

            L 1 Reply Last reply
            0
            • P piul

              I like the idea of having the process in a different thread. It does work much better. However I have a problem when it comes to display in my form the text captured from the process. I have a delegate superMinerThreadWorkCompleted in charge of displaying the results.

              void superMinerThreadWorkCompleted (System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e)
              {
              textBox = "Process text";
              }

              But I get the error C3352: superMinerThreadWorkCompleted(System::Object ^,System::ComponentModel::DoWorkEventArgs ^)' : the specified function does not match the delegate type 'void (System::Object ^,System::ComponentModel::RunWorkerCompletedEventArgs ^)' 1>Form1.cpp in the line

              superMinerThread->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler (&Form1::superMinerThreadWorkCompleted);

              I can fix this by making the delegate static but then I cannot modify member class textBox. What could be the way around this?

              L Offline
              L Offline
              Luc Pattyn
              wrote on last edited by
              #6

              piul wrote:

              DoWorkEventArgs

              piul wrote:

              RunWorkerCompletedEventArgs

              these are different! the former is just wrong. :)

              Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

              Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

              P 1 Reply Last reply
              0
              • L Luc Pattyn

                piul wrote:

                DoWorkEventArgs

                piul wrote:

                RunWorkerCompletedEventArgs

                these are different! the former is just wrong. :)

                Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

                Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

                P Offline
                P Offline
                piul
                wrote on last edited by
                #7

                Changed the delegate to

                void superMinerThreadWorkCompleted (System::Object^ sender,
                System::ComponentModel::RunWorkerCompletedEventArgs^ e)
                {}

                and still got the same error 'void SuperMinerGUI::Form1::superMinerThreadWorkCompleted(System::Object ^,System::ComponentModel::RunWorkerCompletedEventArgs ^)' : the specified function does not match the delegate type 'void (System::Object ^,System::ComponentModel::RunWorkerCompletedEventArgs ^)' 1&gt;Form1.cpp

                L 1 Reply Last reply
                0
                • P piul

                  Changed the delegate to

                  void superMinerThreadWorkCompleted (System::Object^ sender,
                  System::ComponentModel::RunWorkerCompletedEventArgs^ e)
                  {}

                  and still got the same error 'void SuperMinerGUI::Form1::superMinerThreadWorkCompleted(System::Object ^,System::ComponentModel::RunWorkerCompletedEventArgs ^)' : the specified function does not match the delegate type 'void (System::Object ^,System::ComponentModel::RunWorkerCompletedEventArgs ^)' 1&gt;Form1.cpp

                  L Offline
                  L Offline
                  Luc Pattyn
                  wrote on last edited by
                  #8

                  for non-static (instance) delegates, you need a constructor that takes two arguments, the first being this.

                  superMinerThread->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler
                  (this, &Form1::superMinerThreadWorkCompleted);

                  :)

                  Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

                  Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

                  P 1 Reply Last reply
                  0
                  • L Luc Pattyn

                    for non-static (instance) delegates, you need a constructor that takes two arguments, the first being this.

                    superMinerThread->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler
                    (this, &Form1::superMinerThreadWorkCompleted);

                    :)

                    Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum

                    Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.

                    P Offline
                    P Offline
                    piul
                    wrote on last edited by
                    #9

                    Cheers for that!

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups