question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`Application.Init` / `Shutdown` are confused about `TopLevel`s created by `Application.Begin` and not cleaned up by `Application.End`

See original GitHub issue

In UI Catalog, before I start a Scenario I call Application.Shutdown. You are supposed to book end every call to Applciation.Begin with Shutdown.

I just discovered that Shutdown does not actually clean up. As a result, the next time Application.Begin is called, fields like topLevels still have data. This means that the ‘old’ stuff interferes with the ‘new’ stuff.

Short-term fix is to uninitialize stuff:

		/// <summary>
		/// Shutdown an application initalized with <see cref="Init()"/>
		/// </summary>
		public static void Shutdown ()
		{
			Driver.End ();
			foreach (var t in toplevels) {
				t.Running = false;
			}
			toplevels.Clear ();
			Current = null;
			CurrentView = null;
			Top = null;
			MainLoop = null; 
			_initialized = false;
		}

Crux of issue (added Nov 2, 2022 via #2162):

Init/Shutdown are supposed to clean up. But in ResetState, the loop that disposes of the topLevels does nothing because the Toplevel that was created by Init has not been added to topLevels (it gets added by Begin).

The right fix (IMO) would be to move all that state into RunState and leverage the fact that RunState is already IDisposable. However, it may not be possible to do this without a breaking change.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:27

github_iconTop GitHub Comments

1reaction
tigcommented, Nov 3, 2022

See latest update to the PR.

I have implemented your suggested fix (with tweaks). All unit tests except KeyBindings_Command_With_MdiTop pass.

No asserts from UI Catalog.

Check it out!!!

See if you can figure out why that test broke…

1reaction
tigcommented, Nov 3, 2022

Do you think NotifyNewRunState could be invoked safely even if ExitRunLoopAfterFirstIteration is false.

ExitRunLoopAfterFirstIteration as true will exit the RunLoop and it’s needed to manually rerun it. That is only used for drivers that can’t be blocked into the RunLoop, like the WebConsole. But perhaps is safely also to invoke the NotifyNewRunState event if it’s false. I never try it but it should do not screw up anything.

I did this and wrote more unit tests to prove it works. The new docs for these actions are:

		/// <summary>
		/// Notify that a new <see cref="RunState"/> was created (<see cref="Begin(Toplevel)"/> was called). The token is created in 
		/// <see cref="Begin(Toplevel)"/> and this event will be fired before that function exits.
		/// </summary>
		/// <remarks>
		///	If <see cref="ExitRunLoopAfterFirstIteration"/> is <see langword="true"/> callers to
		///	<see cref="Begin(Toplevel)"/> must also subscribe to <see cref="NotifyStopRunState"/>
		///	and manually dispose of the <see cref="RunState"/> token when the application is done.
		/// </remarks>
		public static event Action<RunState> NotifyNewRunState;

		/// <summary>
		/// Notify that a existent <see cref="RunState"/> is stopping (<see cref="End(RunState)"/> was called).
		/// </summary>
		/// <remarks>
		///	If <see cref="ExitRunLoopAfterFirstIteration"/> is <see langword="true"/> callers to
		///	<see cref="Begin(Toplevel)"/> must also subscribe to <see cref="NotifyStopRunState"/>
		///	and manually dispose of the <see cref="RunState"/> token when the application is done.
		/// </remarks>
		public static event Action<Toplevel> NotifyStopRunState;
Read more comments on GitHub >

github_iconTop Results From Across the Web

Bug - Application.Shutdown.CleanupMono never finishes.
Happens randomly with no prerequisites even in TOTALLY empty projects. [ATTACH]
Read more >
A app called 't' always tries to prevent reboots and shut ...
Whenever I try to reboot or shut down my laptop, for a few seconds I see this message: t This app is preventing...
Read more >
Releases · gui-cs/Terminal.Gui
Application.Init / Shutdown are confused about TopLevels created by Application.Begin and not cleaned up by Application.End by @tig in #2167 ...
Read more >
python - How do I close a tkinter window?
You should use destroy() to close a Tkinter window. from Tkinter import * #use tkinter instead of Tkinter (small, not capital T) if...
Read more >
Does "shutdown /s" really not send the "close" signal to ...
Typically the application would do whatever clean-up action is necessary and then close. If the application ignores this message, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found