Solved

Programming hanging, the value is changing at somepoint during execution?

Posted on 2006-11-15
19
257 Views
Last Modified: 2008-01-09
Friends,

I have this code:
Private Delegate Sub UpdateScreenLabelDelegate(ByVal lblToUpdate As Label, ByVal NewValue As String)

    Private Sub UpdateScreenLabel(ByVal lblToUpdate As Label, ByVal NewValue As String)
        Try
            If Me.InvokeRequired Then
                Dim ssd As New UpdateScreenLabelDelegate(AddressOf UpdateScreenLabel)
                Me.Invoke(ssd, New Object() {lblToUpdate, NewValue})
            Else
                lblToUpdate.Text = NewValue ' < when it is here, execution just stops!!! So, I began watching the variables and I notice that there is this circle with two curved arrows, and when you put a mouse over it, it says: "The value of this expression may be incorrect.  It could not be evaluated because: 'error: cannot obtain value' Click this button to reevaluate.
            End If
        Catch ex As Exception
            ShowError(ex.Message.ToString() & "UpdateScreenLabel - AVAOMain")

        End Try
    End Sub

How could it be changing?  What normally causes this type of thing, and how do I fix it?

Thanks in advance!

Eric
0
Comment
Question by:indy500fan
  • 10
  • 7
  • 2
19 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 17948997
I don't know what is the reason, trying to guess.
Remove exception handling from this function - it hides program bugs and doesn't help. Try to replace Invoke with BeginInvoke.
What is program behavior exactly? Does it work withoit debugger and hangs under debugger? Or hangs in any case?
0
 

Author Comment

by:indy500fan
ID: 17949031
AlexFM,

It just hangs in either case.

Hmm...I have been working with it, and I have discovered that the following code, when executed, causes the problem:

    Private Delegate Sub ResetSessionTimeoutDelegate(ByVal TabToShow As TabPage)

    Private Sub ResetSessionTimeout(ByVal TabToShow As TabPage)
        If Me.InvokeRequired Then
            Dim ssd As New ResetSessionTimeoutDelegate(AddressOf ResetSessionTimeout)
            Me.Invoke(ssd, New Object() {TabToShow})
        Else
            ' Make the form visible
            'Me.Visible = True
            'Me.WindowState = FormWindowState.Normal
            'tabAVAO.SelectedTab = TabToShow
            tmrBetweenEventsCheck.Stop()

            ' Sets the timer interval to 30 seconds and start it
            tmrBetweenEventsCheck.Interval = 30000
            tmrBetweenEventsCheck.Start()
        End If
    End Sub

    Private Sub TimerEventProcessor_BetweenSessions(ByVal myObject As Object, ByVal myEventArgs As EventArgs) Handles tmrBetweenEventsCheck.Tick 'Handles tmrBetweenEventsCheck.Tick
        ' Timeout has come, so show the form (weather)
        tmrBetweenEventsCheck.Stop()
        WebBrowser1.Document.Window.Parent.Navigate("http://www.anypage.com")
        WaitForPageToLoad(WeatherInfo)
        Me.WindowState = FormWindowState.Normal
        tabAVAO.SelectedTab = WeatherInfo
    End Sub
    Private Sub FixBrowser()
        WebBrowser1.Document.Window.Parent.ScrollTo(150, 167)
    End Sub

    Private WithEvents tmrWaitForWebLoad As New System.Windows.Forms.Timer()

    Private Sub WaitForPageToLoadTimeout(ByVal myObject As Object, ByVal myEventArgs As EventArgs) Handles tmrWaitForWebLoad.Tick 'Handles tmrBetweenEventsCheck.Tick
        ' Timeout has come, so show the form (weather)
        tmrWaitForWebLoad.Stop()
        FixBrowser()
    End Sub

    Private Delegate Sub WaitForPageToLoadDelegate(ByVal TabToShow As TabPage)

    Private Sub WaitForPageToLoad(ByVal TabToShow As TabPage)
        If Me.InvokeRequired Then
            Dim ssd As New WaitForPageToLoadDelegate(AddressOf WaitForPageToLoad)
            Me.Invoke(ssd, New Object() {TabToShow})
        Else
            ' Sets the timer interval to X seconds and start it
            tmrWaitForWebLoad.Interval = 500
            tmrWaitForWebLoad.Start()
        End If
    End Sub
0
 
LVL 21

Expert Comment

by:mastoo
ID: 17949453
On your initial post, what calls UpdateScreenLabel?  It sounds like recursion, meaning when you update the label it triggers an event that calls UpdateScreenLabel again.  In the debugger, hit pause and look at the call stack to see what is going on.
0
 

Author Comment

by:indy500fan
ID: 17949692
If I hit pause, It only shows one item in the call stack, and that is the line where the problem is.  Does that make sense?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17949782
If program hangs, this can be deadlock. First rule to solve deadlocks - replace all synchronous calls with asynchronous where possible. In your case, replace all Invoke operators with BeginInvoke.
Then add Trace.WriteLine to all functions, before and after every significant action, with apropriate description. Then run the program under debugger and see debug output. This can help to understand the problem.

Typical deadlock situation is the following: thread B makes synchronous request (for example, Invoke) to thread A. At the same time thread A is waiting for something, like completing of thread B (look something like Wait... in your code). Since A is waiting, it doesn't handles Invoke request, thread B doesn't exit - deadlock.
0
 
LVL 21

Expert Comment

by:mastoo
ID: 17950038
I'm not sure why you wouldn't see more of a call stack.  You paused it, and the IDE title says "break" to show that it is paused?  When you're paused, look at the callstack on other threads to see if they make sense.  And how about big picture, what's this code trying to do?
0
 

Author Comment

by:indy500fan
ID: 17950043
AlexFM,

Trying your suggestion now.  May take a while....
0
 

Author Comment

by:indy500fan
ID: 17950066
Mastoo,


There was more, and here it is....
       [Managed to Native Transition]      
       System.Windows.Forms.dll!System.Windows.Forms.Control.WindowText.get() + 0x118 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.Text.get() + 0x2a bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Label.Text.get() + 0x5 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.Text.set(string value = "204.790") + 0x1f bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Label.Text.set(string value) + 0x5 bytes      
>      ActiveVideoAddOn.exe!ActiveVideoAddOn.AVAOMain.UpdateQScreenLabel(System.Windows.Forms.Label lblToUpdate = {System.Windows.Forms.Label}, String NewValue = "204.790") Line 1811 + 0xe bytes      Basic
       [Native to Managed Transition]      
       [Managed to Native Transition]      
       mscorlib.dll!System.Delegate.DynamicInvokeImpl(object[] args) + 0x5a bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackDo(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0x9d bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(object obj) + 0x6b bytes      
       mscorlib.dll!System.Threading.ExecutionContext.runTryCode(object userData) + 0x43 bytes      
       [Native to Managed Transition]      
       [Managed to Native Transition]      
       mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0xa7 bytes      
       mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x92 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallback(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0x90 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbacks() + 0xb3 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x800 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) + 0x45 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.WndProc(ref System.Windows.Forms.Message m) + 0x13 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) + 0x2b6 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0xd6 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 49695, System.IntPtr wparam, System.IntPtr lparam) + 0x75 bytes      
       [Native to Managed Transition]      
       [Managed to Native Transition]      
       System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x2ea bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.WinFormsAppContext}) + 0x17d bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x53 bytes      
       System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext context) + 0x15 bytes      
       Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() + 0xc0 bytes      
       Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() + 0xe4 bytes      
       Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine) + 0x62 bytes      
       [Native to Managed Transition]      
       [Managed to Native Transition]      
       mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x32 bytes      
       Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes      
       mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes      
       mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes      
       mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes      
0
 

Author Comment

by:indy500fan
ID: 17950162
Mastoo,

Okay, big picture, here it Goes:

1. First, my main form (AVAOMain), uses a TCPListener to connect to a TCP Stream, and it looks for valid strings in that stream.  When a valid string is found, it passes the valid string back to to the main form.
2.  In the main form, the valid string is split up, and depending on the type of record, it is passed to another sub that does further processing.
3.  After the string has been split and processed, a screen is modified (labels are set, pictures are brought up, etc.) and formatted with the information gained from the aforementioned processing.  This is where my program is hanging.  
4  Once the screen has been setup, the form is maximized and displayed for a set period of time.  Once the timer expires, the form minimizes.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:indy500fan
ID: 17956847
Okay guys, I've got it working now.  Not perfect, but good enough.

I am using synclock.

For example, before I call the UpdateScreenLabel sub, I declared a new object as follows Dim labelLock as New Object.  Now,

I do the following code:

SyncLock labelLock
  UpdateScreenLabel(...
End SyncLock

With that in mind, is there a better way of doing this?

Thanks,
Eric
0
 
LVL 21

Expert Comment

by:mastoo
ID: 17957758
I was about to suggest using Monitor to block around the Invoke, which is effectively the same thing.  I didn't think it would work this way, but your results make it seem like the message pump jams when the Invoke does a SendMessage and then before returning it does a SendMessage to get/set the label.  Meanwhile, another SendMessage has queued up from the Invoke initiated by another thread.  Unless someone has another explanation?  Your fix seems fine (especially since it works) :-)  You might lock on the form itself if you ever update anything else via invokes.
0
 

Author Comment

by:indy500fan
ID: 17958286
Mastoo,

How do you lock the form?  I still every once in a while still have the problem, and I would like to make sure that I kill it.  So, again, how do I lock the form.
0
 
LVL 21

Expert Comment

by:mastoo
ID: 17958543
"Lock on the form"  I just meant:

SyncLock me

Your threads don't have any interaction with the form other than through the calls to UpdateScreenLabel?
0
 

Author Comment

by:indy500fan
ID: 17958912
Mastoo,

Actually, there are other calls:

The tcplistener, once a valid string is found, sends it to this main form via an event,
Either before or after the call to the update screen label, there is typically a picture of a driver and their car added to the form,
and finally, typically there are other labels that are updated before or after this call, using the UpdateScreenLabel sub.

I thought I was doing each of these actions sequentially, but apparently not. :)  I would like to force sequential updates to the form, so would locking the form accomplish this?

Thanks,
Eric
0
 
LVL 21

Expert Comment

by:mastoo
ID: 17959314
I think if you do similar to each call that updates the form, and all of the locks use the form as the lock object you'll be ok.  I was hoping somebody else would plunge in and give us a good explanation, but based on what you've described it sounds like you just need to prevent the non-Gui threads from calling Invoke while you're updating anything on the form.  Synchronizing with the form as the object will do that.
0
 

Author Comment

by:indy500fan
ID: 17959536
mastoo,

hopefully, this will be my last question on this subject,

If I do the SyncLock Me, where do I incorporate it, with the following code as an example?  Do I do it on the whole sub? or do I do it just before and just after my synclocks in the example below?

 Private Sub SetupQualifierScreen_NewQualifier()
        Try
            Dim lblToUpdate As Label = Nothing
            Dim NewValue As String = Nothing
            Dim ConvertTimeStr As String = Nothing

            'Setup QualStatus Label:

            'lblToUpdate = lblQualStatus
            'NewValue = "New Qualifier"
            'UpdateScreenLabel(lblToUpdate, NewValue)

            'Setup Driver Name Label:
            Dim NewQualDriverName As String = (NewQualLastName & ", " & NewQualFirstName)
            lblToUpdate = lbl_NQ_Driver
            NewValue = NewQualDriverName
            Trace.WriteLine("UpdateScreenLabel is going to be called to update label lbl_NQ_Driver with the value of " & NewValue)
            If lblToUpdate.Text <> NewValue Then
                SyncLock labelLock
                    UpdateScreenLabel(lblToUpdate, NewValue)
                                   End SyncLock
            End If
            FileImageToDisplay = imagePath & "driver\" & NewQualFirstName & NewQualLastName & ".jpg"
            Trace.WriteLine(FileImageToDisplay)

            Dim CheckToSeeIfPictureExists As New CheckIfFileExists.CheckIfFileExists

            DriverPictureExists = CheckToSeeIfPictureExists.ReturnResult(FileImageToDisplay)
            If DriverPictureExists Then
                Trace.WriteLine("DriverPictureExists, so UpdateNQDriverPicture is being called to put up the picture: " & FileImageToDisplay)
                UpdateNQDriverPicture(FileImageToDisplay)
            Else
                PictureBoxUpdateToNothing(pic_NQ_Driver)
            End If
            'Setup CarNumber Label:
            lblToUpdate = lbl_NQ_CarNumber
            NewValue = NewQualCarNumber
            Trace.WriteLine("UpdateScreenLabel is going to be called to update label lbl_NQ_CarNumber with the value of " & NewValue)
            If lblToUpdate.Text <> NewValue Then
                SyncLock labelLock
                    UpdateScreenLabel(lblToUpdate, NewValue)
                  End SyncLock
            End If
            'Setup Car Picture:
            FileImageToDisplay = imagePath & "car\" & NewQualCarNumber & ".jpg"
            Trace.WriteLine(FileImageToDisplay)

            CarPictureExists = CheckToSeeIfPictureExists.ReturnResult(FileImageToDisplay)
            If CarPictureExists Then
                Trace.WriteLine("CarPictureExists, so UpdateNQCarPicture is being called to put up the picture: " & FileImageToDisplay)
                UpdateNQCarPicture(FileImageToDisplay)
            Else
                PictureBoxUpdateToNothing(pic_NQ_Car)
            End If

        Catch ex As Exception
            ShowError(ex.Message.ToString() & "SetupQualifierScreen_NewQualifier - AVAOMain")

        End Try

    End Sub
0
 
LVL 21

Accepted Solution

by:
mastoo earned 500 total points
ID: 17960264
Assuming this sub is on the form, you could either just replace the "SyncLock labelLock" with "SyncLock me" throughout.  Or, since the entire sub deals with updating the form and I assume is being called by the other threads doing non-Gui processing, you could just do the "SyncLock me" for the entire sub.  I think that even makes sense because only one thread at a time can be updating your gui (indirectly via invoke) anyway.
0
 

Author Comment

by:indy500fan
ID: 17960279
Gotcha!  Thanks!
0
 
LVL 21

Expert Comment

by:mastoo
ID: 17961021
Interesting problem - hope it works.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
VB.Net - Find String in Array 3 25
Round a string to two digits 12 24
How to open a link from vb.net app 3 9
Showdialog 8 21
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

759 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now