Note that there are some explanatory texts on larger screens.

plurals
  1. POCalling an external process in C#/WinForms makes UI unresponsive. Why?
    primarykey
    data
    text
    <p>I have a Winforms app that lives in the taskbar area. A window opens up for logging output.</p> <p>Now, in my component (still on UI Thread here) I need to call an external process that runs 5-15min and produces files. I need to wait for the process to exit and consume those files.</p> <p>Since I want my UI to be responsive (move the Window, etc.) I implemented an agent and am calling the process with BeginInvoke/EndInvoke:</p> <pre><code>private delegate int BeginCallDelegate( int port, int baud, int timeout, Job job ); private BeginCallDelegate del = null; public IAsyncResult BeginCall( int port, int baud, int timeout, Job job ) { del = new BeginCallDelegate( Call ); IAsyncResult iar = del.BeginInvoke( port, baud, timeout, job, null, null ); return iar; } </code></pre> <p>In the calling code I am polling the IAsyncResult with WaitOne() but notice that the UI is extremely <em>unresponsive</em> if not <em>frozen</em>:</p> <pre><code>IAsyncResult a = agent.BeginCall(...); //BeginInvoke while ( !a.IsCompleted ) { iar.AsyncWaitHandle.WaitOne( 250 ); //writing something to a textbox works here, but overall responsiveness is weak } agent.EndCall( iar ); //EndInvoke </code></pre> <p><strong>VS tells me the external process is started on a worker thread, but why does that not help with my UI responsiveness? IT should NOT block the calling thread</strong></p> <p>Here's the code that launches the process:</p> <pre><code>ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = "app.exe"; psi.Arguments = String.Format( "blah blah", port, baud, timeout, job.FullName ); psi.CreateNoWindow = false; psi.ErrorDialog = false; psi.WindowStyle = ProcessWindowStyle.Hidden; process.StartInfo = psi; if ( !process.Start() ) throw new Exception( "The process cannot start." ); process.WaitForExit( job.Timeout ); </code></pre> <p><em><strong>Hint: To test, the external app.exe is a dummy app that does nothing else but Thread.Sleep(60000). CPU Load is 3%.</em></strong></p> <p><strong>Another question: How would I do this the "TPL way" without using Begin/EndInvoke?</strong></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload