DataGridView.Refresh() hangs on cross-thread call

D

David Cartwright

Hi all,

I'm having a weird time with a call to the Refresh() method of a
DataGridView. I have a VB.NET 2005 Windows application with a main form and
a "worker" thread. The main form delegates a Sub to the worker so that the
latter can refresh the DataGrid after updating the DataTable driving it.

When I run the app under the debugger, everything's fine. But when I run it
for real, it hangs, apparently in the Refresh() method of the DataGridView -
that is, as soon as I comment out dgRefresh, the hanging goes away.

I'm dealing with the cross-thread issues appropriately, as far as I'm aware:

Public Delegate Sub dgExtRefreshCallback()
Public Sub dgExtRefresh()
dgExtensions.Refresh()
End Sub
Private Sub refreshDGExtensions()
If dgExtensions.InvokeRequired Then
Dim d As New dgExtRefreshCallback(AddressOf dgExtRefresh)
Me.Invoke(d, New Object() {})
Else
dgExtRefresh()
End If
End Sub

.... so it's "refreshDGExtensions()" that is delegated to the worker
class/thread.

I can't help thinking that there's a timing issue somewhere if it's working
in the debugger but not when run from the desktop. I figured I'd throw some
locking in to ensure that (for instance) the DataTable behind the DataGrid
didn't get updated while the DataGrid was refreshing, but that didn't seem
to help. So any ideas would be most welcome!

Thanks a lot,

David C
 
L

Linda Liu [MSFT]

Hi David,

Based on my understanding, you have WinForms application using multithread.
You refresh the data grid view in a thread other than the application's UI
thread. If the program is started with debugger, every thing works fine.
However, if the program is run from the desktop, it hangs in the Refresh
method of the data grid view. As soon as you comment out the statement of
calling the DataGridView.Refresh method, the hanging goes away. If I'm off
base, please feel free to correct me.

Firstly, I'd like to say that your dealing with the cross-thread issue is
appropriate. To ensure that access to your controls is done in a
thread-safe way, we should use the Invoke method of the control.

It seems that race conditions or deadlocks occur in your program from the
phenomenon of the program's hanging. For example, you have locked the data
grid view or data table otherwhere and you require the lock on the data
grid view or data table before you refresh the data grid view.

I think the reason why the problem doesn't occur when the program is
started with debugger is that the conditions for race conditions or
deadlocks aren't met when the program is run with debugger.

I suggest that you check the code in your program to find all places where
the data grid view or data table is locked and then correct them.

Please try my suggestion. If the problem isn't solved, you may make a
sample project that could reproduce the problem and send it to me. To get
my actual email address, remove 'online' from my displayed email address.

Hope this helps.
If you have anything unclear, please feel free to let me know.



Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Cartwright

Hi Linda,
Firstly, I'd like to say that your dealing with the cross-thread issue is
appropriate. To ensure that access to your controls is done in a
thread-safe way, we should use the Invoke method of the control.
It seems that race conditions or deadlocks occur in your program from the
phenomenon of the program's hanging. For example, you have locked the data
grid view or data table otherwhere and you require the lock on the data
grid view or data table before you refresh the data grid view.
I think the reason why the problem doesn't occur when the program is
started with debugger is that the conditions for race conditions or
deadlocks aren't met when the program is run with debugger.

Hi Linda,

Yes, that's my suspicion too. Something somewhere is getting deadlocked, but
under the debugger the timing is such that I'm getting away with it - I
figured that I'd double-check that it wasn't a known .NET bug and that I
wasn't doing anything stupid!

I'll keep digging!

All the best,

D.
 
B

Bart Mermuys

Hi,

David Cartwright said:
Hi all,

I'm having a weird time with a call to the Refresh() method of a
DataGridView. I have a VB.NET 2005 Windows application with a main form
and a "worker" thread. The main form delegates a Sub to the worker so that
the latter can refresh the DataGrid after updating the DataTable driving
it.

When I run the app under the debugger, everything's fine. But when I run
it for real, it hangs, apparently in the Refresh() method of the
DataGridView - that is, as soon as I comment out dgRefresh, the hanging
goes away.

I'm dealing with the cross-thread issues appropriately, as far as I'm
aware:

Public Delegate Sub dgExtRefreshCallback()
Public Sub dgExtRefresh()
dgExtensions.Refresh()
End Sub
Private Sub refreshDGExtensions()
If dgExtensions.InvokeRequired Then
Dim d As New dgExtRefreshCallback(AddressOf dgExtRefresh)
Me.Invoke(d, New Object() {})
Else
dgExtRefresh()
End If
End Sub

... so it's "refreshDGExtensions()" that is delegated to the worker
class/thread.

I can't help thinking that there's a timing issue somewhere if it's
working in the debugger but not when run from the desktop. I figured I'd
throw some locking in to ensure that (for instance) the DataTable behind
the DataGrid didn't get updated while the DataGrid was refreshing, but
that didn't seem to help. So any ideas would be most welcome!

Why do you even need to call Refresh ?

If the DataTable is bound to the DataGridView, then you need to use
Control.Invoke to update the DataTable, then the grid will refresh itself.
If you are inserting rows continous then you'll need to set the worker
thread priority to BelowNormal to give the UI thread the chance to update
properly.

In addition you can also batch the inserts (in a temp table) 10 a 50 rows
then merge them with the DataTable bound to the DGV using Control.Invoke.

HTH,
Greetings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top