Jump to content
Xtreme .Net Talk

Recommended Posts

Posted (edited)

I am writing a data acquisition application for our sensor testing and calibration area and have run into a problem. I had the application working great using a single-thread with Do Events in the looping structures, but didn't like the responsiveness of the UI.

 

So, I did some research and came across the MSDN Magazine Basic Instincts articles on delegates and updating the UI from a secondary thread. It is a great series of articles, which gave me good insight into what I wanted to do. However, implementing it in my application is causing me all kinds of headaches.

 

I use the following method to update my UI from the data acquisition asynchronous method:

 

   '---------------------------------------------------------------------
   'update the user interface with the status
   '
   'status - the status text to display in the StatusBar
   'state - the state of the data acquisition when this call was made (e.g.
   '   "Running", "Completed", or "Cancelled")
   '---------------------------------------------------------------------

   Public Sub UpdateUI(ByVal status As String, ByVal state As String)
       If Me.InvokeRequired Then
           'need to switch to the primary UI thread to perform update
           Dim handler As New UpdateUIHandler(AddressOf UpdateUI)
           Dim args() As Object = {status, state}
           Me.BeginInvoke(handler, args)
       Else
           'on primary UI thread, go ahead and update
           sbStatus.Text = status
           If state = "Completed" Then
               btnSave.Visible = True
               btnRetry.Visible = True
               Beep()
               btnSave.Focus()
           ElseIf state = "Cancelled" Then
               Close()
           End If
       End If
   End Sub

 

It works great when I update the sbStatus text using the command

frmDataAcq.UpdateUI("Change in status text", "Running")

. I can update the status text repeatedly with no problems. The problem occurs when the asynchronous method finishes and the UpdateUI method is called from the following callback method:

 

   '------------------------------------------------------------------
   'called when data acquisition process being run on secondary thread
   'completes
   '
   'ar - arguments passed from process
   '------------------------------------------------------------------

   Private Sub AcquisitionCallBack(ByVal ar As IAsyncResult)
       Try
           Dim returnValue As Boolean
           returnValue = AcquisitionHandler.EndInvoke(ar)
           If returnValue = True Then
               UpdateUI("Finished", "Completed")
           Else
               UpdateUI("Finished", "Cancelled")
           End If
       Catch ex As Exception
           Dim message As String
           message = "Error: " & ex.Message
           UpdateUI(ex.Message, "Cancelled")
       End Try
   End Sub

 

The application hangs at the line

btnSave.Visible = True

in the UpdateUI method. I have read everything I can find by Googling and cannot figure out what I am doing wrong. :confused:

 

Thanks for any insight you can provide,

 

Todd

 

Edit :confused: :

Seems to be rather random.

Edited by tfowler
Posted

Temporary Hang

 

Ok, the problem seems to be a temporary hang, like the UI thread is waiting for something else to happen before anything can run on it. It is really strange (which I guess is expected with multithreading). It seems to be random...sometimes it won't hang, other times it can hang for 5-10 minutes before it finally updates the UI. Again, this only happens when the callback method is called, so the secondary thread should be finished. If I'm just sending updates to the UI, everything runs fine.

 

I appreciate any help I can get,

 

Todd

Posted

Can it be that anything else is updating/using the UI at the same time?

The code in your first post looks correct (although you might want to try Invoke() instead of BeginInvoke() as BeginInvoke allocates some resources that are only cleared if you call EndInvoke() I believe).

 

Only if another event can also trigger a UI update (and if it takes those 5-10 minutes ;) ) might that explain the 'hang' I think. It could also be a long process triggered by the user that isnt handled by a separate thread.

Nothing is as illusive as 'the last bug'.
Posted

Solved...for now

 

Can it be that anything else is updating/using the UI at the same time?

The code in your first post looks correct (although you might want to try Invoke() instead of BeginInvoke() as BeginInvoke allocates some resources that are only cleared if you call EndInvoke() I believe).

 

Only if another event can also trigger a UI update (and if it takes those 5-10 minutes ;) ) might that explain the 'hang' I think. It could also be a long process triggered by the user that isnt handled by a separate thread.

 

Thanks for the help Wile. I tried the Invoke() instead of BeginInvoke() but there was no difference. I also checked through all my code to make sure I wasn't accessing UI objects from outside the UI thread and did not see any issues.

 

Finally, one of the other programmers here opened the code on his machine (using VS2003, while I was using VS2002), it it ran fine...multiple times. So, I went ahead and upgraded my machine to VS2003, and it works fine. I was waiting to upgrade until 2005 was released, but oh well.

 

If it is race condition, it still might not be completely fixed, maybe the timing just changed...but I'm going to continue as if it is fixed and hope nothing changes. At least this is an internal application...so I get to test it on the production computers. :-\

 

Todd

Posted
Finally, one of the other programmers here opened the code on his machine (using VS2003, while I was using VS2002), it it ran fine...multiple times. So, I went ahead and upgraded my machine to VS2003, and it works fine. I was waiting to upgrade until 2005 was released, but oh well.

 

Do you know if the .net framework was also upgraded? VS2003 probably installs 1.1 if not installed yet, it might be that vs2002 uses 1.0 by default. Maybe MS fixed something in between 1.0 and 1.1 regarding this ;).

Nothing is as illusive as 'the last bug'.
Posted
Do you know if the .net framework was also upgraded? VS2003 probably installs 1.1 if not installed yet' date=' it might be that vs2002 uses 1.0 by default. Maybe MS fixed something in between 1.0 and 1.1 regarding this ;).[/quote']

 

Yeah. I had actually already installed 1.1 KB886903 while troubleshooting an ASP.NET issue a couple of months ago. VS2002 would only use 1.0, so hopefully the threading issue was a fix in the latest version of 1.1. Keeping my fingers crossed.

 

Thanks,

 

Todd

Posted
Are you calling into any COM components as part of the non-UI code? IIRC .Net 1.0 had 'issues' with the COM threading model' date=' these were fixed in 1.1[/quote']

 

No. Everything I'm using should be .NET managed code. However, I am accessing drivers and SDK for National Instruments GPIB cards in order to perform the data acquisition. I am using their latest .NET SDK, but you never know about NI. We've had problems with their drivers before. :-\

 

Thanks for the input,

 

Todd

  • 2 months later...
Posted

Last week, I finally figured out what I was doing wrong here and figured I post the solution for everyone else.

 

I was updating a DataSet from the secondary thread that was attached to a DataGrid. It appears that this causes the same problem as updating any other UI element from a secondary thread.

 

So, I created an event in the secondary thread that passes an array of data back to the UI thread. Then the UI thread updates the DataSet. Its a very sneaky problem that had me frustrated for a long time.

 

Todd

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...