Ask a questionAsk a question
 

AnswerCross-thread operation not valid.

  • Monday, August 14, 2006 12:27 PMPaulustrious Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

     

    How should I re-enable a Form after being disabled during an external process?

    I have a Form which calls notepad and while notepad is active it disables itself:

    process.StartInfo.FileName = "notepad.exe";

    process.StartInfo.Arguments = "\"" + file + "\"";

    process.StartInfo.UseShellExecute = false;

    process.StartInfo.Verb = "";

    process.Exited += new EventHandler( process_Exited );

    process.Start( );

    DisableFormDuringEdit( "Editing..." );

    On return, in the event process_Exited event, I tried to enable the form with 'this.enabled=true' but I get the message:

    Cross-thread operation not valid: Control 'MyForm' accessed from a thread other than the thread it was created on.

    I understand the restriction (although not the reason why there is such a restriction). What is the best way to send a signal from the process_Exited event to the form? Here are two ways that seem to work, but it probably does not include the best.

     

    1) Disable cross thread checking:

    System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;

    this.enabled = true;

    System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = true;

     

    2) Timer 

    Create a timer on the form, and in the process_Exited event start the timer which immediately exits and enables the form.

    What is the correct way to do what I wish?

     

    Regards - Paul

Answers

  • Monday, August 14, 2006 1:08 PMSalvaPatuel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Hi,

    You should invoke your method on the correct thread, you can do this delegating the function (sync with Invoke or Async with BeginInvoke).

    The restriction is because the UI thread is the main gdi thread that draws your interface, Microsoft does not want you to change things that are under that thread responsibility as you can crash, lock , a priority inversion or generate a race condition on the UI thread. .NET 2.0 enforces that rule that was overlooked on .NET 1.1.

    About your solutions,

    1) Not recommended as you are jumping the restrictions

    2) The timer runs in another thread (from the pool) so you will have the same problem.

    Hope this helps,

    Cheers

     

All Replies

  • Monday, August 14, 2006 12:50 PMMattias SjögrenMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    3. Use Control.Invoke to call a method on the UI thread that enables the Form.

     

  • Monday, August 14, 2006 1:08 PMSalvaPatuel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Hi,

    You should invoke your method on the correct thread, you can do this delegating the function (sync with Invoke or Async with BeginInvoke).

    The restriction is because the UI thread is the main gdi thread that draws your interface, Microsoft does not want you to change things that are under that thread responsibility as you can crash, lock , a priority inversion or generate a race condition on the UI thread. .NET 2.0 enforces that rule that was overlooked on .NET 1.1.

    About your solutions,

    1) Not recommended as you are jumping the restrictions

    2) The timer runs in another thread (from the pool) so you will have the same problem.

    Hope this helps,

    Cheers