Exit() doesn't work

I’m currently upgrading my project to latest Development Build for Visual Studio, and I noticed that Exit() doesn’t work.
I have to close the game by pressing x in Console Application (used for debugging purposes) or by ending the process in Task Manager.

Specs: Win10, VS2015, latest Development Build with DesktopGL template.


P.S. How do I unlock FPS? I have had debug button to toggle FPS lock on-off to see how heavy some of my game areas are, but it doesn’t work anymore. Here’s the code I used in 3.5:

 graphics.SynchronizeWithVerticalRetrace = !graphics.SynchronizeWithVerticalRetrace;
 IsFixedTimeStep = !IsFixedTimeStep;
 graphics.ApplyChanges();

Why not just set those 2 to false?

It’s possible IsFixedTimeStep is false by default, if that is the case you are always having 60fps with your code

1 Like

I found a workaround.
At start I just set IsFixedTimeStep and Synchronizing to false, apply changes and immediately lock FPS again. That way I can toggle FPS normally, its weird but it works.

When initializing game in Game1(), I now have

graphics.SynchronizeWithVerticalRetrace = false;
IsFixedTimeStep = false;
graphics.ApplyChanges();

ToggleFrameRate();

and ToggleFrameRate() is just

graphics.SynchronizeWithVerticalRetrace = !graphics.SynchronizeWithVerticalRetrace;
IsFixedTimeStep = !IsFixedTimeStep;
graphics.ApplyChanges();

If I call

Exit();
  • It stops the Update loop
  • It closes the “graphics part”
  • Something stays running in background
  • Music keeps playing
  • I have to close the game from either task manager or by hitting close button in console application.

If I call

Exit();
Environment.Exit(0);

It completely closes the game.

Is calling Environment.Exit(0) ok?

Aren’t you using a thread in your app ?

You have to do an ApplyChanges(); twice ? Thats curious.

You don’t have to call ApplyChanges in your constructor because the GraphicsDevice hasn’t been created yet. And you should make sure to kill your threads before exiting.

No, there is only the main thread, no other threads. Do I have to kill main thread somehow?
And I have had ApplyChanges() after changes because otherwise the FPS unlock / lock doesn’t work for some reason.

So no one knows fix to Exit() problem, other than calling Environment.Exit(0)?

Weird thing is, Exit() seems to work fine on empty projects :confused:

My project is not multithreaded, so I could it have something to do with Loaded Content or graphics settings?

How are you playing your music?
Could you set up a github project so that we may debug? It’s hard without code.

1 Like

The game is a college project, and the college owns the source so I cannot share it openly.

Music files are .OGG and .MP3 converted to .OGG with Content Pipeline, played with

MediaPlayer.Play(song);

Sound files are .WAV files, with few being .OGG converted to .XNB with Content Pipeline, played like this:

SoundEffect sound = GetSound("soundname");
SoundEffectInstance sfx = sound.CreateInstance();
sfx.Volume = volume;
sfx.Pitch = pitch;
sfx.Pan = pan;
sfx.Play();

I create SoundEffectInstances, so that I can track how many instances of the sound are playing at the same time, and avoid ear rape by not playing same sound too many times in a row.
When I’m done with the Sounds, I get rid of them with

SoundEffectInstance sfx = FinishedSounds[i]
sfx.Stop();
sfx.Dispose();

To be clear, “Exiting” works, but the process doesn’t close.
If I run the game in Visual Studio, the game screen / window closes, but when run from .exe it doesn’t,it just freezes.

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    Exiting += Shutdown;
}

public void Shutdown(object sender, EventArgs e)
{
    //Checking if Shutdown works, and it does.
    Console.WriteLine("Exiting Game")
}

Hmmm.
The good news is that you’re doing everything correctly.
You could pool your SoundEffectInstances since those are objects and disposing them leads to garbage, but that’s a technicality with no relevance to your problem at hand.

The bad news is that, obviously, we’re missing something here since it really should exit when calling Exit(), like your empty project does. Hell, I have a game here using multithreading, async loading and so on and I use Exit() like you do and it works.

So maybe it’s time to take the new project, copy some code over there until it doesn’t stop when calling Exit(). That sounds horrible but at least you’ll find the culprit.
Maybe you can use TaskManager to look at the not-closing game. Attach the debugger to that process and pause execution and see where you are.
You say it exits flawlessly when debugging in VS??

1 Like

Hmm pooling sounds good idea.
When debugging in VS, the game window closes, but process doesn’t.

Going through code by hand will take some time, but I guess that it is one of the only options here.

You could try the debugging thing… VS - debugging - Attach to process… then pause execution and look where you’re standing.

1 Like

If I have Just My Code enabled, I get
“The application is in break mode, Your app has entered a break sate, but there is no code to show because all threads were executing external code (typically system or framework code).” Also, there are no tasks to display.

If I disable Just My Code, I get this:

Can you put a breakpoint on the Exit() call, and see what you can find as suspect in the call stack, or threads, or modules, or parallel stack ?

2 Likes

I found the problem, it was the game’s code all along.

I got a bright idea to test Exit() at start of the game, before initializing anything, and guess what: it didn’t work.
At this point, I jumped over to Program.cs, because it was the only thing called before the game itself. First, everything looked fine, until I compared my game’s Program.cs to empty project.

For some reason, I had

var game = new Game1();
game.Run();

While empty project had

using (var game = new Game1())
    game.Run();

I don’t know what the real difference here is, but I changed my game to match that and it magically worked!

Thanks for everyone involved in this topic :slight_smile:

1 Like

Using calls dispose at the end. So when not using it you inadvertently didn’t free unmanaged resources and that prevented your game from stopping .

Nice find. Wouldn’t have looked there at all.

:smile: