Results 1 to 5 of 5

Thread: [2008] Prevent cross-threading exceptions outside a class

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Dec 2005
    Location
    In front of my pc
    Posts
    78

    [2008] Prevent cross-threading exceptions outside a class

    I'm designing a class that makes use of threads. These threads sometimes fire events, and when these events are handled in a form(outside of the class), they cause cross-threading exceptions. Now of course I can solve this by using Invoke methods or delegates, but I wonder if I could code the class in such a way the problem is already solved inside the class, this would make the class way more user-friendly. I couldn't find any clear solution on the web, that's why I'm asking here. Any kind of documentation/tutorial/example on this subject is welcome

  2. #2
    Frenzied Member bmahler's Avatar
    Join Date
    Oct 2005
    Location
    Somewhere just west of the Atlantic
    Posts
    1,568

    Re: [2008] Prevent cross-threading exceptions outside a class

    yes you can. I ran into this sort of thing a long time back. What you can do is create a constructor for your class that accepts a System.ComponentModel.ISynchronizeInvoke parameter and pass that the form that is using the class.
    for exmple
    Code:
            ''' <summary>
            ''' Gets or sets the object to invoke to avoid illegal cross thread calls
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property SyncObject() As ISynchronizeInvoke
                Get
                    Return Me._syncObject
                End Get
                Set(ByVal value As ISynchronizeInvoke)
                    Me._syncObject = value
                End Set
            End Property
    Code:
            ''' <summary>
            ''' Create a new instance of the chatlog class
            ''' </summary>
            ''' <param name="iSyncObject">The object that will be invoked (this is used to avoid illegal cross thread 
            ''' calls when updating controls on a form from the newline event)</param>
            ''' <remarks></remarks>
            Public Sub New(ByVal iSyncObject As System.ComponentModel.ISynchronizeInvoke)
                Me.SyncObject = iSyncObject
                If Not Initialize() Then
                    MsgBox("Unable to initialize... FFXI must be running")
                End If
            End Sub
    Then you can handle all of the possible cross thread calls in the class like so
    Code:
            ''' <summary>
            ''' Function called from within the thread to call the newline event.  If the SyncObject is set, it will check if InvokeRequired and do so if necessary
            ''' </summary>
            ''' <param name="iLineInfo"></param>
            ''' <remarks></remarks>
            Protected Overridable Sub OnNewLine(ByVal iLineInfo As ChatLine)
                If iLineInfo.MsgID > _firstLine Then
                    If Me.SyncObject IsNot Nothing AndAlso Me.SyncObject.InvokeRequired Then
                        Me.SyncObject.Invoke(New LineAdded(AddressOf OnNewLine), New Object() {iLineInfo})
                    Else
                        RaiseEvent NewLine(iLineInfo)
                    End If
                End If
            End Sub
    And when creating an instance of the class you just pass the form that will be using it so as to prevent any cross thread calls.
    Code:
    Dim c As New ChatLog(Me)
    Boooya
    • Visual Studio 2008 Professional
    • Don't forget to use [CODE]your code here[/CODE] when posting code
    • Don't forget to rate helpful posts!
    • If you're question was answered please mark your thread [Resolved]


    Code Contributions:
    PHP
    PHP Image Gallery v1.0PHP Image Gallery v2.0
    VB 2005
    Find Computers on a networkSimple License EncryptionSQL Server Database Access dllUse Reflection to Return Crystal ReportDocumentSilently Print PDFGeneric Xml Serailizer


    Useful Links: (more to come)
    MSDN (The first and foremost)MSDN Design Guidelines API Reference • Inno Setup CompilerInno Setup PreprocessorISTool - Fairly easy to use GUI for creating inno setup projects • Connection StringsNAnt -Automated BuildsCruise Control .NET - Frontend for automated builds

  3. #3
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: [2008] Prevent cross-threading exceptions outside a class

    Hmm.. this is a very interesting little tip. I wonder what are the comparisons between this method and the use of delegates, in terms of reliability and speed?

  4. #4
    Frenzied Member bmahler's Avatar
    Join Date
    Oct 2005
    Location
    Somewhere just west of the Atlantic
    Posts
    1,568

    Re: [2008] Prevent cross-threading exceptions outside a class

    This uses delegates as well but you simply pass in the the form object so that you can invoke it from the class. I didn't put the delegate in my example as i figured he already knew to use a delegate.
    My delegate is used here.
    Code:
            ''' <summary>
            ''' Function called from within the thread to call the newline event.  If the SyncObject is set, it will check if InvokeRequired and do so if necessary
            ''' </summary>
            ''' <param name="iLineInfo"></param>
            ''' <remarks></remarks>
            Protected Overridable Sub OnNewLine(ByVal iLineInfo As ChatLine)
                If iLineInfo.MsgID > _firstLine Then
                    If Me.SyncObject IsNot Nothing AndAlso Me.SyncObject.InvokeRequired Then
                        Me.SyncObject.Invoke(New LineAdded(AddressOf OnNewLine), New Object() {iLineInfo})
                    Else
                        RaiseEvent NewLine(iLineInfo)
                    End If
                End If
            End Sub
    Boooya
    • Visual Studio 2008 Professional
    • Don't forget to use [CODE]your code here[/CODE] when posting code
    • Don't forget to rate helpful posts!
    • If you're question was answered please mark your thread [Resolved]


    Code Contributions:
    PHP
    PHP Image Gallery v1.0PHP Image Gallery v2.0
    VB 2005
    Find Computers on a networkSimple License EncryptionSQL Server Database Access dllUse Reflection to Return Crystal ReportDocumentSilently Print PDFGeneric Xml Serailizer


    Useful Links: (more to come)
    MSDN (The first and foremost)MSDN Design Guidelines API Reference • Inno Setup CompilerInno Setup PreprocessorISTool - Fairly easy to use GUI for creating inno setup projects • Connection StringsNAnt -Automated BuildsCruise Control .NET - Frontend for automated builds

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [2008] Prevent cross-threading exceptions outside a class

    FYI, the most common classes that implement this interface are the FileSystemWatcher and System.Timers.Timer (the other Timer that used to be in the VS.NET 2003 Toolbox). When you create a FileSystemWatcher or Timer in code, by default they will raise their events on a thread pool thread. When you add one to a form in the designer, that form is automatically assigned to their SynchronizingObject property and they will this raise their events on the thread that owns the form.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width