Results 1 to 15 of 15

Thread: [RESOLVED] Communicating across threads from module to gui text box

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Dec 2007
    Posts
    22

    Resolved [RESOLVED] Communicating across threads from module to gui text box

    I have tried to follow jmcilhinney's post at http://www.vbforums.com/showthread.p...Worker-Threads

    I have a thread that relies on functions/subs that exist inside a module (I know people do not like modules since everything is pretty much public...but humor me )

    The module has a sub that is supposed to write text to a textbox on the gui thread. That sub will be ran from another thread that is running the logic\processing, and not the gui thread. I was using delegates and checking for invokeRequired on the textbox before invoking the sub, but it just seems to do nothing. no errors, just nothing.


    My code snippets are as follows:


    Code in Module
    ---------------------
    Code:
    Public Delegate Sub WriteTo_txtLog_Invoker(ByVal LogEntry As String) 'DECLARED WITHIN MODULE BEFORE SUBS
    
    
    Public Sub LogErrors(ByVal ErrMsg As String)
            'TODO: handle writing error to file
    
    
           'Write error to GUI TextBox
    
            WriteTo_txtLog(ErrMsg)
            End Sub
    
    
    Public Sub WriteTo_txtLog(ByVal LogEntry As String)
            If frmMain.txtLog.InvokeRequired = True Then
                frmMain.txtLog.Invoke(New WriteTo_txtLog_Invoker(AddressOf WriteTo_txtLog), LogEntry) 
            Else
                frmMain.txtLog.Text = LogEntry & frmMain.txtLog.Text
            End If
        End Sub
    frmMain is the ....main form lol, on the gui.


    It seems weird because it looks like I am following the process in that post above....but nothing happens even when i purposely call the logErrors sub from the logic/processing thread.

    Any help would be greatly appreciated!

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

    Re: Communicating across threads from module to gui text box

    The issue is that you are using the default instance to refer to the form and default instances are thread-specific. InvokeRequired will never be True because referring to the default instance on the secondary thread simply creates a new instance on that thread. It belongs to that thread so InvokeRequired is False and the code goes ahead and modifies that instance, but it is not the instance that you displayed on the UI thread in the first place. You have two main options:

    1. Add a property/field to that module to refer to the main form. Have the main form assign itself to that property/field in the first place, so you know that it refers to the correct instance.
    2. Use the SynchronizationContext class.

    If you use option 1 then you code doesn't change much. If you want to use option 2 then there's an example later in that CodeBank thread of mine.
    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

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Dec 2007
    Posts
    22

    Re: Communicating across threads from module to gui text box

    Hmm, I apologize as I am still in the process of trying to learn more of the details to programming. could you elaborate on option 1?

    I really do appreciate this help. You have been making understanding threading a much more clear task.

  4. #4
    Lively Member
    Join Date
    Apr 2010
    Posts
    82

    Re: Communicating across threads from module to gui text box

    Your issue is nmot to do with threading.

  5. #5
    Bad man! ident's Avatar
    Join Date
    Mar 2009
    Location
    Cambridge
    Posts
    5,401

    Re: Communicating across threads from module to gui text box

    Your Module references no instance to frmMain. Your are simply using it's default instance. Is there a particular reason you are using Module? And there really is no need to be writing a custom delegate.

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

    Re: Communicating across threads from module to gui text box

    I think that you're trying to make it harder than it is. You already know how to declare a variable and assign a value to it. That's all option 1 is.
    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

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

    Re: Communicating across threads from module to gui text box

    Quote Originally Posted by freeblog View Post
    Your issue is nmot to do with threading.
    Yes it is.
    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

  8. #8
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Communicating across threads from module to gui text box

    One thing I would add is that the problem is more due to modules than threading. Threading is the proximate problem, but the ultimate problem is more one of organization. People don't object to modules because they are "pretty much public" because they aren't. You make things public when you declare them public. If you declared elements of a module as Private, then they would not be Public....but they'd still be in modules. A module is a class with all members Shared. If you need a class with all members Shared, then a module is an excellent solution. In fact, it is an easier solution than actually creating a class with all shared members since you don't need to use the module name when refering to members of a module.

    The problem with modules is that they are often used in place of a better design. They are not the wrong answer when they are used appropriately, but they are the wrong answer (as is anything else) when they are used inappropriately. In your case, the useage is inappropriate. After all, your method doesn't work on just any form, or even any instance of the main form. Instead, it works with only one specific instance of one specific form. If you try to use it for any other instance of any other form, it simply won't work. In this case, you actually ARE using it with another instance of a form, and that's where your problem lies, but you thought you were still working with the one instance of the one form, so it isn't quite the same thing.

    The point of Object Oriented design is to encapsulate data, and the methods that work with the data, into a single code construct (a class). A module is no different, except that, since all the members are Shared, the class works with only a certain set of data (usually the union of the set of data passed to the method and the set of global data). In your case, you have the set of data with your main form and the set of methods that work on data in your main form (including the controls, which are just members of the main form) all in the main form....and then you have this other method that just happens to work with that main form and nothing else, but which is sitting off somewhere else in the program. A whole different file, in fact. That's pretty awkward organization:

    All the things in here are the class....plus one other item that is found somewhere totally separate.
    My usual boring signature: Nothing

  9. #9

    Thread Starter
    Junior Member
    Join Date
    Dec 2007
    Posts
    22

    Re: Communicating across threads from module to gui text box

    frmMain is what is loaded on startup. Is there a method of setting a variable within the module to the existing instance of frmMain?

    I tried declaring a variable in the module as Windows.Forms.Form , then when frmMain loads, i set that variable = ME

    will that then allow me to reference the particular instance of the form?


    CODE IN MODULE
    =================
    Code:
    Public frmMainInst As Windows.Forms.Form 'DECLARED WITHIN MODULE, BEFORE SUBS

    CODE IN frmMain
    =================
    Code:
    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                    frmMainInst = Me
        End Sub

  10. #10
    Bad man! ident's Avatar
    Join Date
    Mar 2009
    Location
    Cambridge
    Posts
    5,401

    Re: Communicating across threads from module to gui text box

    Please read what has already been said. A module should not be used.

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

    Re: Communicating across threads from module to gui text box

    Quote Originally Posted by dontstealmyfish View Post
    frmMain is what is loaded on startup. Is there a method of setting a variable within the module to the existing instance of frmMain?

    I tried declaring a variable in the module as Windows.Forms.Form , then when frmMain loads, i set that variable = ME

    will that then allow me to reference the particular instance of the form?


    CODE IN MODULE
    =================
    Code:
    Public frmMainInst As Windows.Forms.Form 'DECLARED WITHIN MODULE, BEFORE SUBS

    CODE IN frmMain
    =================
    Code:
    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                    frmMainInst = Me
        End Sub
    You've got the code already. Why ask us whether it will work when you could just try it for yourself? If it works then you don't need to ask the question. If it doesn't work then the question is not "will it work" but rather "why didn't it work".
    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

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Dec 2007
    Posts
    22

    Re: Communicating across threads from module to gui text box

    Quote Originally Posted by ident View Post
    Please read what has already been said. A module should not be used.
    Ok, but i would still need to be able to reference the form instance as I am trying to communicate across threads, right? That is what I am trying to figure out so that the invoking and invokeRequired will work.

  13. #13

    Thread Starter
    Junior Member
    Join Date
    Dec 2007
    Posts
    22

    Re: Communicating across threads from module to gui text box

    Quote Originally Posted by jmcilhinney View Post
    You've got the code already. Why ask us whether it will work when you could just try it for yourself? If it works then you don't need to ask the question. If it doesn't work then the question is not "will it work" but rather "why didn't it work".
    Ah, you are right. Sorry, I guess I was just nervous and posted before testing. It looks like it won't work when i reference the instance of the form itself, but will if i reference the instance of the textbox.

    When I tried to reference the proper frmMain, it would do so... but then i could not access the textbox inside that form instance.

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

    Re: Communicating across threads from module to gui text box

    Quote Originally Posted by dontstealmyfish View Post
    When I tried to reference the proper frmMain, it would do so... but then i could not access the textbox inside that form instance.
    That's because you declared the field as type Form and that type has no fields that refer to TextBoxes. If you know that the type of the object you want to refer to is frmMain then declare the field as that type. There's no reason not to. You'd only use Form if you want to be able to refer to different types of forms.
    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

  15. #15

    Thread Starter
    Junior Member
    Join Date
    Dec 2007
    Posts
    22

    Re: Communicating across threads from module to gui text box

    Quote Originally Posted by jmcilhinney View Post
    That's because you declared the field as type Form and that type has no fields that refer to TextBoxes. If you know that the type of the object you want to refer to is frmMain then declare the field as that type. There's no reason not to. You'd only use Form if you want to be able to refer to different types of forms.
    Perfect, Thanks! Definitely learned a few things today that I will not forget! declaring the variable as a type of specific form is exactly what I needed to do.

Tags for this Thread

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