Results 1 to 17 of 17

Thread: [RESOLVED] Referencing a Form on a Seperate Thread...?

  1. #1

    Thread Starter
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Resolved [RESOLVED] Referencing a Form on a Seperate Thread...?

    I converted my code from VS2003 to VS2005 and came across a threading issue. In 2003, it worked without a problem, but now 2005 complains about Cross-Threading.

    I created a "Progress Bar Form" which when displayed, runs the ShowDialog() method on a seperate thread in order to allow the calling thread to continue processing, yet maintain the ShowDialog() features. Problem is that calling ShowDialog() without a parent form parameter can cause the form to display in strange location on your screen. So I added the option to define the parent form to which the "Progress Form" would center against. Problem is, that when the "Progress Form" is displayed on a secondary thread, it is passed a reference to the parent for it to center on, which is now on a different thread (the main thread), and VS2005 crashes complaining about Cross-Threading.

    Now, I am relatively new to Multi-Threading, and I have gotten some migrains debugging Threading problems before . I was hoping that someone here would be able to give me some idea's or pointers on how I can fix this particular Cross-Threading issue...?
    Last edited by BSantiag; Aug 28th, 2006 at 02:04 PM.
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

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

    Re: Referencing a Form on a Seperate Thread...?

    There are examples all over the forum. .NET 2.0 provides the BackgroundWorker for a start, which hides some of the complexity of multi-threading. You call RunWorkerAsync in the UI thread and this raises the DoWork event in a worker thread. No need for you to explicitly create a thread. In the worker thread you can call ReportProgress and this will raise the ProgressChanged event in the UI thread. This handles crossing the thread boundary without any explicit intervention from you. When the DoWork event handler completes the RunWorkerCompleted event is raised in the UI thread, notifying your app that the operation is complete and, again, negating the need for you to code explicitly to cross the thread boundary. You should read up about the BackgroundWorker class. If you want to stick to coding everything yourself then search the forum for my user name with the key word "invokerequired" and you'll find several examples of access control members across thread boundaries.
    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
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Re: Referencing a Form on a Seperate Thread...?

    Although I am relatively new to the concept of Threading, I do understand most of it and I am somewhat familier with the BackgroundWorker concept. Unfortunatly, all this previous Threading code was written in 2003 and I am under a time constraint. I just need to fix it so that it behaves properly without causing errors in VS2005. I will post the code below in the hopes of clarifying what it is I am looking for.

    VB Code:
    1. Public Sub Display(Optional ByVal objParentForm As Object = Nothing)
    2.         '************************************************************************
    3.         ' Procedure/Function: Display()
    4.         ' Author: Ben Santiago
    5.         ' Description:
    6.         '       Display the Thermometer form on it's own thread.
    7.         '************************************************************************
    8.  
    9.         '***************************************
    10.         ' If Parent Form Supplied, Store Reference
    11.         '***************************************
    12.         If Not IsNothing(objParentForm) Then
    13.             Me._objParentForm = objParentForm
    14.         End If
    15.  
    16.         '***************************************
    17.         ' Display Thermometer Form (Threaded)
    18.         '***************************************
    19.         Dim objNewThread As New Threading.Thread(AddressOf DisplayThreaded)
    20.         objNewThread.Start()
    21.         Threading.Thread.Sleep(1000)
    22.     End Sub
    23.  
    24.     Private Sub DisplayThreaded()
    25.         '************************************************************************
    26.         ' Procedure/Function: DisplayThreaded()
    27.         ' Author: Ben Santiago
    28.         ' Description:
    29.         '       Display the Thermometer form.
    30.         '************************************************************************
    31.  
    32.         If Not IsNothing(Me._objParentForm) Then
    33.             Me._objThermometerForm.ShowDialog(Me._objParentForm) '<-- This Causes a Cross-Threading Error
    34.         Else
    35.             Me._objThermometerForm.ShowDialog()
    36.         End If
    37.     End Sub
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

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

    Re: Referencing a Form on a Seperate Thread...?

    Quote Originally Posted by jmcilhinney
    If you want to stick to coding everything yourself then search the forum for my user name with the key word "invokerequired" and you'll find several examples of access control members across thread boundaries.
    Ya dig?
    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

  5. #5

    Thread Starter
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Re: Referencing a Form on a Seperate Thread...?

    I did understand, there was no confusion to what you said in the previous post, so yes “I Dig”. I did check the posts regarding InvokeRequired, but I couldn’t see how any of the information that came up was specifically relevant to the problem I am coming across. I posted my code in order to clarify my problem in the hope that someone would understand and be able to steer me in a proper direction.

    InvokeRequired along with the Invoke method from what I understand is what you use to modify an object that exists on another thread. I am not trying to modify the ParentForm, I just want to pass it's reference so that the ThermometerForm centers against it.

    What I don’t understand is how to pass the reference to a form on Thread #1, to a form that I am using on Thread #2. It all boils down to one line of code that is causing the Cross-Thread.
    VB Code:
    1. ' This line of code is run on Thread #2
    2. _objThermometerForm.ShowDialog(_objParentForm)
    3.  
    4. ' Note:
    5. '   _objThermometerForm exists on Thread #2
    6. '   _objParentForm exists on Thread #1
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

  6. #6
    Fanatic Member TokersBall_CDXX's Avatar
    Join Date
    Mar 2003
    Location
    America
    Posts
    571

    Re: Referencing a Form on a Seperate Thread...?

    Bleh, working on this as well..
    Build your own personalized flash based chat room for your webpage for FREE! http://www.4computerheaven.com

  7. #7
    Fanatic Member TokersBall_CDXX's Avatar
    Join Date
    Mar 2003
    Location
    America
    Posts
    571

    Re: Referencing a Form on a Seperate Thread...?

    are Me._objThermometerForm and Me._objParentForm dynamically loaded forms?
    Build your own personalized flash based chat room for your webpage for FREE! http://www.4computerheaven.com

  8. #8

    Thread Starter
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Re: Referencing a Form on a Seperate Thread...?

    Ok, umm...short answer:
    Me._objParentForm = Form Reference passed to the Display()
    Me._objThermometerForm =
    Previously: Created when the parent class was created (in the contructor)
    Currently: Created dynamically at the time Display is called.

    I have been tweaking the code trying to figure this out, hence the two different versions... I can post or send you the code if youw ant to see it...
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

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

    Re: Referencing a Form on a Seperate Thread...?

    '_objThermometer' is a control and 'ShowDialog' is a member of that control. I have posted multiple examples of using a delegate to access a member of a control from a worker thread. You will find them by performing the search I suggested.
    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

  10. #10

    Thread Starter
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Re: Referencing a Form on a Seperate Thread...?

    Originally Posted by jmcilhinney
    '_objThermometer' is a control and 'ShowDialog' is a member of that control. I have posted multiple examples of using a delegate to access a member of a control from a worker thread. You will find them by performing the search I suggested.
    First off let me start by saying that I re-read every single posting on this site that came up on a search for InvokeRequired; a total of 22 message threads. None of the articles related to the specific problem that I am encountering. Second, regarding the quoted text above...I do not have a problem accessing the ShowDialog() method. The way my code operates, ShowDialog() is always executed on the same thread that it's form was created on. When the ShowDialog() method executes without parameters, it works perfectly fine, its when I add a reference to the calling form (which exists on another thread) that I encounter the Cross-Threading problem.

    Now, I in no way shape or form claim that I am an expert in Threading (obviously since I am posting my threading problem here). But I am not foreign to Marshalling and threading, being that I have used it on several occassions. The code I am having a problem with now, worked perfectly fine in VS2003, and only now is a problem in VS2005 because of it's stricter rules. I would rather fix my code to work properly as per the languages rules, rather that set the flag to ignore Cross-Threading errors. I don't think that using that flag is an option.

    From what I understand, ShowDialog() places a ThreadBlock on the calling thread. Since my main form is on the UI thread, I don't want that behavior, so I create the Thermometer form on a secondary thread so that when ShowDialog() is executed, the ThreadBlock is placed on the secondary thread instead of the UI thread. Problem is that when you pass no parameters to the ShowDialog() method, it places the form (usually) in the upper left corner of your screen, which I do not want. In order to center on the proper screen I need to pass the method a reference to a parent form. When I pass the reference to the parent form (which exists on another thread) is when I encounter the Cross-Threading problem.

    Is what I am trying to do is not possible? Maybe my whole approach to how I am going this is wrong, but its what I previously had written. If I have to, I can rewrite it, if someone can show me another way of accomplishing what I need. But I tend to think that there should be a way for me to accomplish what I am looking for.
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

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

    Re: Referencing a Form on a Seperate Thread...?

    You could set the dialogue form's StartPosition to Manual and then position it yourself, based on the Location and Size of the intended parent form. That would negate your having to specify a parent simply to set the Location of the form.

    Are you creating this worker thread purely to show this dialogue, or is it doing other things too?
    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
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Re: Referencing a Form on a Seperate Thread...?

    Originally Posted by jmcilhinney
    You could set the dialogue form's StartPosition to Manual and then position it yourself, based on the Location and Size of the intended parent form. That would negate your having to specify a parent simply to set the Location of the form.

    Are you creating this worker thread purely to show this dialogue, or is it doing other things too?
    I thought about the Manual setting of the forms position, but then I lose the benefit of the ShowDialog, which makes the form Modal. This form is being placed on a Worker thread so that when ShowDialog() is executed, the worker thread is blocked and not the UI thread. So yes, the main purpose of the worker thread is to show the form. The form itself is just a "Progress Bar Indicator" form that is updated by work performed on another thread.
    Last edited by BSantiag; Sep 1st, 2006 at 07:17 AM.
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

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

    Re: Referencing a Form on a Seperate Thread...?

    From the sound of that last post, I think you're going about this the wrong way. You're saying that you want the progress dialogue to be centred over the main form but you don't want it prevent access to that form. I would just show the progress dialogue as either a regular form (using Show()) or a modeless dialogue (using Show(Me)) from the main form in the UI thread. I would then spawn the worker thread from that dialogue. That way you get exactly the behaviour you want.
    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

  14. #14

    Thread Starter
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Re: Referencing a Form on a Seperate Thread...?

    Originally Posted by jmcilhinney
    From the sound of that last post, I think you're going about this the wrong way. You're saying that you want the progress dialogue to be centred over the main form but you don't want it prevent access to that form. I would just show the progress dialogue as either a regular form (using Show()) or a modeless dialogue (using Show(Me)) from the main form in the UI thread. I would then spawn the worker thread from that dialogue. That way you get exactly the behaviour you want.
    Actually, you got that wrong. I DO want to prevent access to the form, what I DON'T want is to prevent the CODE that is already running from doing so.
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

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

    Re: Referencing a Form on a Seperate Thread...?

    Have the first form pass the data to the second for that it needs and then show it as a modal dialogue. You can't have your cake and eat it too. If that's not good enough then hide the first form so that the user can't access it. To use multi-threading in this situation is, in my opinion, a very bad idea. It's no wonder I couldn't work out what was supposed to be happening.
    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

  16. #16
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Referencing a Form on a Seperate Thread...?

    Quote Originally Posted by jmcilhinney
    You can't have your cake and eat it too.
    http://wsu.edu/~brians/errors/eatcake.html

    Quote Originally Posted by jmcilhinney
    To use multi-threading in this situation is, in my opinion, a very bad idea.
    I disagree.

    Quote Originally Posted by BSantiag
    So I added the option to define the parent form to which the "Progress Form" would center against.
    Why not just pass the coordinates?
    Or, better, have the actual work done in a thread separate from the entire GUI. That way you avoid the problem in the first place.

  17. #17

    Thread Starter
    Member BSantiag's Avatar
    Join Date
    Aug 2006
    Location
    New York
    Posts
    38

    Re: Referencing a Form on a Seperate Thread...?

    Originally Posted by jmcilhinney
    To use multi-threading in this situation is, in my opinion, a very bad idea. It's no wonder I couldn't work out what was supposed to be happening.
    I have to disagree, I think that this is a creative way to use Multi-Threading in order to have a form behave in a manner that does not intrude on the processing of code on a working thread. As for not being able to figure out what was happening, unfortunately I have run out of ways to explain what it is I am trying to do.

    Originally Posted by jmcilhinney
    You can't have your cake and eat it too.
    Well it turns out that I can "Eat my cake and have it too." I rewrote the logic behind the Manager Class and the Thermometer Form. I decided to try to see if I could override the ShowDialog method and add some special handling, I could not Override, but I could Overload the method, which I did. I then changed my ShowDialog(FormObject) line to a straight forward ShowDialog(). In the ShowDialog Overloaded method, I added some code that accesses the Manager Class of the form to see if a Parent Form was supplied in the original Display Method, and if so, uses the reference to that form to calculate the position of the newly displaying Thermometer Form. I set the Start Position to Manual, set the location and then call MyBase.ShowDialog(). This allowed me to position the form centered on the parent, while continuing to keep the inherent propertied of the ShowDialog() method of making the form Modal.

    Originally Posted by penagate
    Why not just pass the coordinates?
    Or, better, have the actual work done in a thread separate from the entire GUI. That way you avoid the problem in the first place.
    Coordinate passing might have worked, but I took the route of just calculating internal to the Manager Class. As for having the work done out of the GUI, the problem is, that this ManagerClass/ThermometerForm is a generic universally useable Class. I have no way of knowing in what situation it will be used, and has already been used in several different capacities. It could be instantiated directly from the GUI or from a Worker Thread. Wherever it’s called from, I have to make sure that I do not inadvertently block THAT thread, hence the additional thread just for display purposes. Either way I was able to work out my dilemma, thank you so much for your input.
    Ben Santiago, MCP & A+
    Programmer Analyst(SQL, FoxPro, VB, VB.Net, Java, HTML, ASP, JSP, VBS)
    Eastern Suffolk BOCES - Student Data Services


    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
    -Rich Cook

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