-
-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InvalidOperationException("View has been garbage collected.") #2
Comments
Thanks for reporting this issue, it is appreciated. Do you have code you can share, or perhaps create a small application where it is possible to reproduce the exception? I am otherwise somewhat coding in the dark when trying to find the bug you are describing. Again, thanks! |
Hi, many thanks for your rapid response, it's much appreciated. There really isn't any meaningful "code to share" - our code is literally just setting DialogResult to true or false in a view model that implements IModalDialogViewModel. Any sample or simple test case will do the same. To reproduce the issue, simply open and close modal dialogs repeatedly. After doing that a few times (and after a GC occurs while so doing), the problem occurs. Thanks again. |
Please take a look at my branch where the last commit has modified a coded UI test to constantly use the modal dialog feature. The test will indefinitely open a modal dialog and then close it using a My problem is that the test doesn't throw the exception you stated. Can you please help me by specifying the changes I need to do to the test in order for it to throw the exception you stated? |
Hi, thanks for investigating this. I have spent some time on this today (took a little while to get used to the unfamiliar code) and have not yet been able to reproduce it in your test case. However... I noticed that the test case was creating the AddTextDialog, but this was not then entering the code path seen in the call stack when it was closed. After some exploration, I determined that this was because the AddTextDialog is not registered with DialogServiceViews, and was able to use this information to narrow down the scope of the problem. In our code, we see the exception thrown when a dialog that can itself be a parent to other dialogs is closed; in your test case, I was able to more closely simulate the situation by adding md:DialogServiceViews.IsRegistered="True" into AddTextDialog.xaml. When the AddTextDialog is closed, it now goes into MvvmDialogs.DialogServiceViews.OwnerClosed etc. as seen in the call stack. As noted, I've still not been able to cause it to throw. (On the basis that the exception complains that the "View has been garbage collected", it seems likely to be related to GCs and when they happen; I tried allocating arbitrary amounts of memory to try to cause it to GC at the crucial time and trigger the problem, but without success so far). However, registering the AddTextDialog with the service views is at least one step towards reproducing the problem. I am unfortunately now off work until Tuesday, and will continue investigating then. But since you have been so responsive with your replies, I thought it would be a good idea to update you with my progress. Thanks for your help so far. |
I have spent some more time today attempting to create a reliable repro case in the automated test suite, without success. I appreciate this makes it difficult for you to investigate. |
Unfortunately I haven't had the time myself to investigate the issue further. There is either a bug in my code or in yours. Hopefully I will have some time in the near future to investigate, but it would of course go much quicker if I had a reproducible scenario. Thank you very much for the time and effort you've put into this. |
Hello, |
If both of you are experiencing the same problem I guess it has to be something with MVVM Dialogs. Unfortunate that none of you can reproduce it. Are you logging in your applications? If so I could perhaps add logging to MVVM Dialogs that you would be able to send be after the issue occurred? |
...either that or we're both making the same mistake. Which I like to think we're not, but is possible. ;-) Just want to add that we have recently seen it a couple of times on shut-down as well, though closing a dialog is more typical (guess it goes through the same code-path). Our project is still at a fairly early stage and doesn't have logging set up yet, though it's something we should be adding soon... between that and not having been able to reproduce the problem in your automated test suite, I appreciate this doesn't make it any easier for you to investigate. OTOH, if the logging is in place, we can provide a simple file-logger to it really easily, without needing to set up our entire logging framework. Thanks for your continued responsiveness, I know how frustrating it can be when users report issues without being able to provide either logs or a repro case! |
I think I can implement something that we can use even though you haven't yourself implemented logging in your application. What I am thinking is something in the lines of: MvvmDialogs.Logging.Logger.Log = message => Trace.Write(message); or perhaps if we would like to log to a file: MvvmDialogs.Logging.Logger.Log = LogToFile;
private static void LogToFile(string message)
{
using (StreamWriter writer = File.AppendText("log.txt"))
{
writer.WriteLine(message);
}
} Do you think that would be possible? |
Yes, that would be fine, that's an extension point we can easily attach something to, even if it's just a simple file logger like you show for now. |
I've released v1.2.0. It contains the property Please let me know if you find something useful. |
Not sure how useful it will be, there's not much in there; but the attached is a log from a crash we just observed while shutting down the application. As before, this threw the "View has been garbage collected" exception shown in the OP. |
I've attempted to fix the issue by investigating the logs. Please download the pre-release NuGet package by writing:
in the Package Manager Console. If your issue is solved, I'll do a new official release. Thank you again for being very helpful in this issue. |
I've installed the new (pre-release) version... so far so good, but since the issue is intermittent it's hard to guaranteed it's fixed just yet; we'll leave it a few days before giving the all-clear. Thanks again for your responsiveness. |
Any news regarding this issue? |
Sorry for the lack of update, most of us have been out of the office over the Xmas break. We've still not seen the error happen since your updated build, though as an intermittent issue and the fact not many of us have been around, I'm not sure how compelling that is as evidence of a fix! :-) |
We can wait one more week. |
FYI we've still not seen any further occurrences since installing the pre-release version. Looks like a good fix AFAICT. Thanks again for your help and responsiveness with this issue, it's much appreciated. |
Fixes #2. Preventing throwing exception by pruning the views before unregistering a view.
Version 1.2.16 has now been released and can be downloaded using NuGet. Thank you very much for your feedback regarding the issue and don't hesitate coming back with more issues you encounter. Thank you! |
Occasionally, after setting DialogResult = true (or false) in an IModelDialogViewModel using OpenDialog, an exception is thrown from the following location:
...that is, for some reason the simple act of setting DialogResult = true leads to a cascade of calls within the MvvmDialogs code that causes the viewReference to be disposed but still modified.
Top of the call stack at the point the exception is thrown:
at MvvmDialogs.Views.ViewWrapper.get_Source()
at MvvmDialogs.DialogServiceViews+<>c__DisplayClass4.b__2(MvvmDialogs.Views.IView)
at System.Linq.Enumerable.Any[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Generic.IEnumerable
1<System.__Canon>, System.Func
2<System.__Canon,Boolean)at MvvmDialogs.DialogServiceViews.Unregister(MvvmDialogs.Views.IView)
at MvvmDialogs.DialogServiceViews.OwnerClosed(System.Object, System.EventArgs)
at System.EventHandler.Invoke(System.Object, System.EventArgs)
at System.Windows.Window.OnClosed(System.EventArgs)
at System.Windows.Window.WmDestroy()
at System.Windows.Window.WindowFilterMessage(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr, IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.HwndSubclass.DefWndProcWrapper(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr, IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.UnsafeSendMessage(IntPtr, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr)
at System.Windows.Window.InternalClose(Boolean, Boolean)
at System.Windows.Window.Close()
at System.Windows.Window.set_DialogResult(System.Nullable
1<Boolean>) at MvvmDialogs.DialogService+<>c__DisplayClass1.<RegisterDialogResult>b__0(System.Object, System.ComponentModel.PropertyChangedEventArgs) at System.ComponentModel.PropertyChangedEventHandler.Invoke(System.Object, System.ComponentModel.PropertyChangedEventArgs) at GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanged(System.String) at LifecycleCRM.UI.ViewModels.InterestedPartyViewModel.set_DialogResult(System.Nullable
1)...which is all happening within the ShowDialog call.
The text was updated successfully, but these errors were encountered: