views:

182

answers:

2

My problem feels very similar to the issue mentioned in this post. Essentially, Invoke is hanging (only when run outside the debugger). I think it's due to nesting of Invoke calls.

I'm using MVVM Light, and I've tried two implementations of a multi-thread friendly ObservableCollection - I've used this one for ages and recently tried to simplify to this version. The latter seemed better until it failed with a "owned by this thread" InvalidOperationException. And looking at my copy of the former, looks like I'm swallowing exceptions in there. Naughty naughty. This would be the reason for the property changed "failures".

Here is the flow of operation that is troublesome. At nearly every point, I've tried moving things to the ui thread or moving them off the ui thread. I have managed to defer hanging, but at the expense of property changed failures.

  • Request comes in from thread over WCF to primary ViewModel
  • Request is parsed (I've tried both on the background thread and invoking to the main thread)
  • ReportEntry object is retrieved from database
  • Message sent to UI through Messenger requesting edit dialog be shown.
  • Main Window handles message, IEditableObject.BeginEdit is called and the edit dialog is shown.
  • Upon return the Messenger callback Action is called.
  • The ReportEntry is now ready to be added to its proper collection. MainViewModel has a collection of FileViewModels which each have a collection of ReportViewModels.
    • The ReportViewModels are usually created by the FileViewModel watching the FileModel's collection's CollectionChanged events. I've tried bypassing this to avoid more nesting, to no avail.

It is at this point that my app either hangs (if I'm operating primarily on the main thread) or CollectionChanged events fail due to threading, depending on how I've moved things between threads.

When the app hangs, it is in a wait called from Invoke, according to the debugger I attach.

Oh and I've tried changing various Invoke's to BeginInvoke's.

To summarize I need an answer to one of these two questions:

  1. What puts my UI thread into a wait mode such that Invoke is hanging?
  2. Is there a better ObservableCollection-derived class to use for this?

Thanks for pondering.

UPDATE

Well, I don't know whether to delete this question and start over or what. It appears the problem is tied to a ListCollectionView I was using to filter the ReportEntry's. My FileViewModel has a

public ListCollectionView FilteredReports {get; private set;}

initialized like so:

FilteredReports = new ListCollectionView(Reports);
FilteredReports.Filter = FilterFunction;

When I remove FilteredReports, there is no more hanging. Annoyingly, the DataGrid I'm using this view as the ItemsSource for is in a DataTemplate, so moving the filter to my view is non-trivial as well. So, any reason for ListCollectionView to be hanging on Collection updates?

+1  A: 

Hi Tom,

Instead of answering let me ask. In the "app hangs" scenario, have you tried "Break when an exception is CLR exception" option under debugger?

Yes, I read your post carefully, you said it is not hanging under debugger (Heisenbug). Just want to be sure there are no exceptions (even binding or layout related).

I'm asking this because in very rare scenarios, I've seen deadlocks deep in WPF internals, when unexpected exception occurs (I considered them as Mandelbugs). And fixing that exception also fixed deadlock problem.

Anvaka
Well, unfortunately, I have so many exceptions at this point that it hard to run when breaking on throw. I've worked around the issue for now (trying to get a build out before the end of the year), but I do expect to come back and try the viewmodel route again. That will be my first debugging step.
Tom
No exceptions, no clue what's going on. However its no longer a Heisenbug. It just plain hangs. I seem to be deadlocking the app somehow. I'd think my CollectionView should behave essentially the same as the one created by my wpf toolkit datagrid.
Tom
A: 

Make sure that your ListCollectionView itself isn't being created on a background thread. I had this same problem and found that advice on http://social.msdn.microsoft.com/Forums/en/wpf/thread/410a0b39-dfdb-4115-8a68-4ccabc17bcb6. I indeed was doing that and making sure that the ListCollectionView was constructed on the UI thread solved my "hanging" problem.

Mike