Tech Off Thread

5 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

The Importance of Multi-Threading Handlers

Back to Forum: Tech Off
  • User profile image

    Tuesday, October 26, 2004: Understanding Chris Sells Teachings about Multi-Threading in Windows Forms: The Importance of Multi-Threading Handlers

    Chapter 14 of Chris Sells, his book Windows Forms Programming in Visual Basic .NET (with Justin Gehtland on drums) explains all we need to know about implementing multi-threading designs in all but the most complex Windows Forms. Unfortunately, I had to read this chapter about five times and I had to send several stern emails to Chris Sells (which he generously answered) before I understood these basic bits:

    ·        Creating a worker thread can be an indirect procedure (by calling BeginInvoke) or it can be a direct procedure by getting a new Threading.Thread object. Sells discuses the disadvantages of using the latter method but I find I am able to name a new Threading.Thread object and sets is priority—I will tentatively call these “advantages.”

    ·        Think about implementing multi-threading handlers in the same manner you think about implementing error handling: every method that interacts with the UI thread (and is likely to be called from a worker thread) must be designed with a pattern that interrogates the Boolean InvokeRequired for true. The following is the Chris Sells multi-threading handler design pattern (written with my sense of style):

    Delegate Sub MySubDelegate(ByRef WinForm As MyNameSpace.MainForm)
    Sub MySub(ByRef WinForm As MyNameSpace.MainForm)

        If WinForm.InvokeRequired Then

            Dim del As MySubDelegate _

                = New MySubDelegate(
    AddressOf MySub)

            Call WinForm.BeginInvoke(del, New Object() {WinForm})


            With WinForm

                'TODO: Do stuff to objects on the UI Thread.

            End With

        End If

    End Sub
    'How will Windows Forms 2.0 eliminate the need for this pattern?

    ·        When InvokeRequired is always true, the flawed design is probably calling Invoke() or BeginInvoke() from an object created on the worker thread. The design pattern above avoids making this mistake by clearly showing that it is WinForm making the call (there is, believe me, the temptation to use del.BeginInvoke, which is incorrect—it puts wrinkles in Sells’ Burning Man kilt!).

    ·        Calling back to the UI thread from the worker thread means calling from an object that ultimately derives from System.Windows.Forms.Control that was instantiated by the UI thread.

    ·        The ISynchronizeInvoke interface contains the aforementioned worker-thread-to-UI-thread method invocations and the Boolean indicator that such an invocation is required. As of this writing, only one class implements this interface System.Windows.Forms.Control. Explaining why the ISynchronizeInvoke interface exists in the first damn place would have gone a long way toward why multi-threading handlers are important.

    ·        There is the temptation to make all Windows Forms event handlers multi-threading handlers as well. I find that this design goal creates too much code what with the writing of delegates for every single event handler. Another way is to not set form control properties directly in event handlers but to create a Client Layer of static methods that set Windows Forms controls, each with their delegates and multi-threading handlers.

    ·        When all of the above bits are found to be valid and not addressed by Windows Forms 2.0 kudos to the brilliant author who thunk it all up! Until then, these ideas are all my fault. Sorry, Chris.

  • User profile image

    Interesting question re Forms 2.0.

    Does anybody know if there are improvements to the BeginInvoke / InvokeRequired/Is-my-code-back-running-on-the-UI-thread arena?

  • User profile image

    Simo wrote:
    Interesting question re Forms 2.0.

    Does anybody know if there are improvements to the BeginInvoke / InvokeRequired/Is-my-code-back-running-on-the-UI-thread arena?

    Chris S. and Justin G. send me email.We're close and stuff Wink They assure me that all of this stuff multi-threading handling will be very, very gone in WinForms 2.0. Now Chris has the inside track in Microsoft; he says as much as he is allowed to about this topic. He does not volunteer much information (to me) about exactly how this is going to happen---but he says it's going to happen.

  • User profile image
    Mike Dimmick

    The new piece is, I think, the BackgroundWorker class. This handles all the mess of getting code running on a thread-pool thread, firing progress events back to the thread that created it, supporting cancellation of background operations, and notifying the creating thread of successful, cancelled, or unsuccessful completion.

    See How to: Run an Operation in the Background.

    That's general CLR/Base Class Library 2.0 stuff. There may be even better WinForms-specific support that I'm not aware of.

  • User profile image

    Mike Dimmick wrote:
    The new piece is, I think, the BackgroundWorker class.

    Looks useful. I can see a lot of potential with BackgroundWorker.ProgressChanged.

    But what happens when DoWork contains a call to an object with events wired up to the UI thread? What Boolean will InvokeRequired equal inside the event handler(s)?

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.