?
Solved

Quick 500 - Need help on Threading; a nice puzzle for you guru's :)

Posted on 2005-03-31
2
Medium Priority
?
217 Views
Last Modified: 2010-04-23
Hi,

I'm been working on a CommandButton UserControl that is passed a stored procedure. When a button is pressed, It calls the Results from the database and then displays the information in a seperate form which is then aligned to the UserControl.

This is all working until today when i decided that i wanted the Database call which takes a few seconds to be done in a seperate thread... Everything is working fine, but by the time the Call finishes the forms are flashing visible then disappearing.

I've tracked the point in which the forms disappear, there are no dispose calls being made or anything like that, unfortunatly this is where it gets interesting... the Forms are disappearing when the cursor ends a subroutine.

I've made a simple peice of code for you guys to compile
You need to breakpoint the 'End Sub' which i've clearly marked

Do the following....
Make a normal Windows Project
Add another project to the solution - Select Windows Control Library
In the new UserControl... Draw a new button (no need to rename)

now go into the Code of the USer control and Paste the Following:


'***************************************************

        Private Delegate Sub DataSet_WorkCompleted(ByVal ObjRows() As DataRow)
        Private m_ResultCallback As DataSet_WorkCompleted
        Private ObjSearchResults As SearchResults
    Private WithEvents ObjFrmResults As New Form1

    Private Sub Cmd_Search_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'The Search button was Clicked.. Open the Wrapper and Populate it with the Parameters and SP info
        Try

            m_ResultCallback = AddressOf Populate_Results
            ObjSearchResults = New SearchResults(m_ResultCallback)
            Dim ObjThread As New Threading.Thread(AddressOf ObjSearchResults.Search)
            ObjThread.Start()
            'ObjSearchResults.Search()

        Catch ex As Exception
            'Error stuff
        End Try
    End Sub

    Private Sub Populate_Results(ByVal ObjDataRows() As Data.DataRow)
        'Show the form
        ObjFrmResults.Show()
        ObjFrmResults.TopMost = True
    End Sub


    Private Class SearchResults
        Private m_CallBackThread As DataSet_WorkCompleted

        Public Sub New(ByRef CallBackWhenCompleted As DataSet_WorkCompleted)
            m_CallBackThread = CallBackWhenCompleted
        End Sub
        Public Sub Search()
            Dim ObjRow(5) As DataRow

            'This is where the DB call goes...
            System.Threading.Thread.Sleep(5000)

            'By now the ObjRow would be populated also...

            m_CallBackThread(ObjRow)


        End Sub 'BREAKPOINT HERE <-------
    End Class

'**************************
Now... Rebuild the solution and paste the Usercontrol onto the first project's form....

After breakpointing the 'End Sub' that i've marked.... Run the project and click the Button, You should see a new form (topmost for debug) appear on top of the existing form and the breakpoint kick off...

This is where my results are displayed.... but as soon as you Step through so the cursor goes past the End Sub, the Form disappears

I think this is something to do with the GC killing it all off because the form is obviously running on the same thread (my best guess) but i can't figure out how to make the form stay :/

If you can figure out this little puzzle the 500 is yours :D

Thanks in Advance
0
Comment
Question by:Cloud9_User
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 9

Accepted Solution

by:
Lacutah earned 2000 total points
ID: 13673344
The problem is that your created thread is trying to alter the user interface.  Only the main thread can alter the user interface ( Private Sub Populate_Results)

One way around this is the use of delegates - when the data has been retrieved, having the created thread call ObjFrmResults.Invoke(Delegate), which would force the called delegate to run under the main thread.

The other way is to create a delegate and use it's BeginInvoke and EndInvoke.
Here's an example on how to do it - I am not using the class you created in your code above, so it's a bit simpler:
    'Define a delegate Structure
    Private Delegate Function delSearch() As DataRow()
    'Create a Delegate Object of type delSearch
    Private d As New delSearch(AddressOf GetData)
    Sub Cmd_Search_Click()  'Whatever event should start the ball rolling.
        'The following cruns GetData on a seperate thread, and when
        'done executing, calls HasData on the current thread.
        d.BeginInvoke(New AsyncCallback(AddressOf HasData), Nothing)
    End Sub
    'This function will run on a seperate thread.
    Function GetData() As DataRow()
        '... Get Data Here ..., return DataRows...
        'Return SomeRows
    End Function
    Sub HasData(ByVal ar As IAsyncResult)
        'The next line retrieves the datarows from the non-ui thread...
        Dim myDataRows() As DataRow = d.EndInvoke(ar)
        ObjFrmResults.Show()
        ObjFrmResults.TopMost = True
    End Sub
0
 

Author Comment

by:Cloud9_User
ID: 13680937
Brilliant.... the First example solved my Problem, except in my Actual code i'm passing the UserControl anyway... So i just did UserControl.Invoke

Thanks!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: jpaulino
XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
Article by: Kraeven
Introduction Remote Share is a simple remote sharing tool, enabling you to see, add and remove remote or local shares. The application is written in VB.NET targeting the .NET framework 2.0. The source code and the compiled programs have been in…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Suggested Courses
Course of the Month8 days, 20 hours left to enroll

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question