XNA Lags when window has focus
I'm developing for xna game studion using XNA 3.1, and I've noticed a problem with some games, where they lag despite the system having plenty of resources to handle them, along with an inexplicable excess of processor usage. When the window from the game is in focus, process #1 (in task manager) goes to 100% usage, and the game shows signs of minor lag (largely notable when sound effects are repeated in sequence). When the game loses window focus, it continues to draw and update at real time, but the process usage decreases, and the lag disappears.
I have tested this with various games, and the results remain the same, pro开发者_JS百科ving that it has nothing to do with my code or code efficiency.
Is this a problem isolated to Xna 3.1, and is there fix for it? Or do I just have to switch to 4.0 and hope my games don't use anything that isn't backwards compatible?
The problem may occur because of garbage collector. Everytime garbage collector runs, the frame rate may drop for a second or two, though on Windows it shouldnt be a problem.
Add this line to your code and see how much heap memory is generated. Every time the value goes down, garbage collector is ran.
SpriteBatch.DrawInt64(FONT, GC.GetTotalMemory(false) / 1000 /* in kilobytes */, new Vector2(5, 30), Color.White, 0f);
SpriteBatch.DrawInt64 is a SpriteBatch extension which doesnt generate garbage on int, long etc. You can alternatively just use SpriteBatch.DrawString(..., (GC.GetTotalMemory(false) / 1000).ToString(), ... )
SpriteBatchExtensions.cs : http://pastebin.com/z9aB7zFH
XNA, from my experience, runs up to 60 frames per second while in focus, and at about 20 frames per second when out of focus. IF however, you have set IsFixedTimeStep = false;
the game will run as fast as it possibly can when the process is in focus. With my game, on my machine, it runs at about 500-700 fps. This is also tied in to the number of Update()
calls that occur. So my game is also updating 500-700 times per second.
My bet is that you have disabled the fixed timestep, and the massive number of Update and Draw calls are consuming 100% of your core and it is messing with your music. I would recommend removing the line IsFixedTimeStep = false;
if it's there. If that line does not exist in your code, this is not the problem, although I would bet that your Update or Draw is doing more work than it should be.
Just noticed this in my own game, I have a Console.WriteLine statement (for debugging) in my update loop, this causes lots of lag.
XNA add a sleep when the window is not in focus! I solved this problem some time ago overriding Game class and changing the way the Game class understand its form is active or not.
There is not way, as much as i know, to disable this behaviour without modifying Game class behaviour with code.
In particular, the way i found some time ago is a real hack\quirk! Very unclean solution, but the only way i found.
public class MyGame
{
private MethodInfo pActivate;
public MyGame()
{
// We need to access base HostActivate method, that unfortunally, is private!
// We need to use reflection then, of course this method is an hack and not a real solution!
// Ask Microsoft for a better implementation of their class!
this.pActivate = typeof(Game).GetMethod("HostActivated", BindingFlags.NonPublic | BindingFlags.Instance);
}
protected sealed override void OnDeactivated(object sender, EventArgs args)
{
base.OnDeactivated(sender, args);
// Ok, the game form was deactivated, we need to make it believe the form was activated just after deactivation.
if (!base.Active)
{
// Force activation by calling base.HostActivate private methods.
this.pActivate.Invoke(this, new object[] { sender, args });
}
}
}
精彩评论