How to correctly write Data with PowerShell to GUI controls from a different Run

This topic contains 1 reply, has 2 voices, and was last updated by Profile photo of Don Jones Don Jones 2 years, 1 month ago.

  • Author
    Posts
  • #19754
    Profile photo of Peter Kriegel
    Peter Kriegel
    Participant

    First of all excuse me for my bad English.

    How to correctly write Data with PowerShell to GUI controls from a different Runspace

    PowerShell is a single threaded application.
    If PowerShell creates a Graphical User Interface (GUI) and should do other things (in the background) it
    can not react on events that are produced by the GUI.
    The user has the impression that the GUI is frozen (blocked).
    To force PowerShell to do 2 things at the same time you can use PowerShell Jobs or use PowerShell runspaces.
    PowerShell Jobs do not support easy access to Objects inside so we use runspaces to run the GUI.
    PowerShell runspaces are a kind of a thread inside the PowerShell Process so the word Thread and runspace are used interchangeably here.

    Access to Windows Forms controls is not inherently thread safe.
    If you have two or more threads manipulating the state of a control,
    it is possible to force the control into an inconsistent state.
    Other thread-related bugs are possible as well, including race conditions and deadlocks.
    It is important to ensure that access to your controls is done in a thread-safe way.

    There was one thing that bothers me all the Time:
    How can I create a non blocking GUI with PowerShell which does not need a synchronized hash table.
    To operate your GUI through a synchronized hash table is like to operate your whole living room through a keyhole

    Microsoft suggests the following pattern to make thread-safe calls to Windows Forms controls:
    1. Query the control's InvokeRequired property.
    2. If InvokeRequired returns true, call Invoke with a delegate that makes the actual call to the control.
    3. If InvokeRequired returns false, call the control directly.

    See: How to: Make Thread-Safe Calls to Windows Forms Controls
    http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.85%29.aspx
    and dokumentation of the System.Windows.Forms.Control.Invoke or System.Windows.Forms.Control.BeginInvoke methods.

    In the fact that we know that we are running the GUI his own thread the use of InvokeRequired is not necessary.
    So we allways use the System.Windows.Forms.Control.Invoke ore System.Windows.Forms.Control.BeginInvoke methods here.

    Even Windows Presentation Foundation (WPF) uses the Invoke and BeginInvoke Methods of the System.Windows.Threading.Dispatcher class to
    make Thread-Safe calls to WPF controls

    Here I present a Pattern how to make thread-safe calls to Windows Forms controls
    I think you can adopt it easily to WPF

    Credits are going to:
    Simon Mourier See: http://stackoverflow.com/questions/14401704/update-winforms-not-wpf-ui-from-another-thread

    For code see here:
    http://poshcode.org/5520

    if you have a better solution to this problem or have questions / suggestions, please write it.

    gereets Peter Kriegel

  • #19817
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Thanks!

You must be logged in to reply to this topic.