-
Notifications
You must be signed in to change notification settings - Fork 685
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
#3330 broke Dialog
Dispose
#3338
Comments
Well, it seems that you need to dispose the toplevel on the End method. // Do NOT dispose .Toplevel here. It was not created by
// Run, but Init or someone else.
runState.Toplevel?.Dispose ();
runState.Toplevel = null;
runState.Dispose (); |
No. That's not correct. The creator of the object needs to be responsible for its lifetime. With my fix, anywhere someone creates a toplevel to pass to Run must dispose the object after Run returns. I've got a pr in profess that will fix all instances in the solution. |
My thinking about this isn't the disposing on the |
But I think that disposing the |
Window w = new ();
w.Ready += (s,e) { Application.RequestStop() }; // Causes `End` to be called
Application.Run(w);
if (w.SomeProperty) {} // Invalid - w has been disposed
Applicaton.Run(w); // Invalid - w has been disposed See this new unit test: [Fact]
public void End_Should_Not_Dispose_ApplicationTop_Shutdown_Should ()
{
Init ();
RunState rs = Application.Begin (Application.Top);
Application.End (rs);
#if DEBUG_IDISPOSABLE
Assert.True (rs.WasDisposed);
Assert.False (Application.Top.WasDisposed);
#endif
Assert.Null (rs.Toplevel);
var top = Application.Top;
Shutdown ();
#if DEBUG_IDISPOSABLE
Assert.True (top.WasDisposed);
#endif
Assert.Null (Application.Top);
} If the old Tons of unit tests re-use If If If If If a |
But isn't normal that referencing a toplevel (w) after the call We need to have sure what is the right behavior before continue. |
Before #3330 runState.Toplevel?.Dispose ();
runState.Toplevel = null;
runState.Dispose ();
// BUGBUG: Application.Top is now invalid?!?! This is incorrect behavior: a) An example of Scenario code that SHOULD fail (it would if we threw exceptions on property access for disposed objects) is var open = new OpenDialog { Title = "Open", AllowsMultipleSelection = true };
Application.Run (open);
if (!open.Canceled)
{
foreach (string path in open.FilePaths)
{
if (string.IsNullOrEmpty (path) || !File.Exists (path))
{
return;
}
// TODO should open in focused TabView
Open (new FileInfo (path), Path.GetFileName (path));
}
} If this code is changed to the below, the bug would be illustrated: var open = new OpenDialog { Title = "Open", AllowsMultipleSelection = true };
Application.Run (open);
Assert.True (open.WasDisposed); It's only luck that the check for My fix does this: // Do NOT dispose .Toplevel here. It was not created by
// Run, but Init or someone else.
runState.Toplevel = null;
runState.Dispose (); (and changes I believe the new code is correct. The downside of the "Fix" is that it means anyone who creates a var open = new OpenDialog { Title = "Open", AllowsMultipleSelection = true };
Application.Run (open);
bool canceled = open.Canceled;
if (!canceled)
{
foreach (string path in open.FilePaths)
{
if (string.IsNullOrEmpty (path) || !File.Exists (path))
{
break;
}
// TODO should open in focused TabView
Open (new FileInfo (path), Path.GetFileName (path));
}
}
open.Dispose (); |
It's true that |
We really need some tight-focused unit tests for all this. It's crazy complicated and the only code that really exercises it are the "BackgroundWorker" Scenarios which are NOT good test cases as they are convoluted and do many things. Since you have a good idea in your head of how this is supposed to work, could you please engineer some unit tests that prove #3399 does/does not break the logic? |
A possible fix on this PR tig#24. |
Fixes gui-cs#3338. Application.Run/End -> Callers must dispose Toplevel
Fixes #3338. `Application.Run/End` -> Callers must dispose Toplevel
Well THAT was fun. ;-) |
I broke something in
Application.End
leavesTop
invalid #3330Not sure how I missed this in my testing.... and clearly more/better unit tests are needed.
Repo:
You'll get an assert that the Dialog for the about box was not disposed.
The text was updated successfully, but these errors were encountered: