运行更新后由GC收集的XNA游戏

时间:2012-03-10 12:45:06

标签: c# multithreading garbage-collection xna


我正在编写一个返回游戏模式(int)和IP地址(字符串)的启动画面。想法是启动屏幕运行,接受用户输入,然后使用这些选项运行主游戏。我正在使用一个线程来实现这一点 - 线程轮询来自启动屏幕的退出请求,然后将值拉出到program.cs并在启动时调用exit()。

主游戏独立运行,没有任何问题,但启用了启动画面,游戏只运行1帧,并且在运行更新方法后似乎被垃圾收集处理掉了。 (如果尝试引用它,则返回DisposedObjectException或类似的东西)经过一些调试后,我发现问题出在exit命令中。代码如下:

using System;
using System.Threading;

namespace SplashScreen
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            int choice = 0;
            string ip = "";
            bool runSplash = true;
            bool useThreading = true;
            bool ignoreThreadResponse = false;
            // Debug option, toggle running splash screen
            if (runSplash == true)
            {
                bool splashrunning = true;
                using (Splash1 splash = new Splash1())
                {
                    if (useThreading)
                    {
                        // Run a thread to poll whether the splash screen has requested an exit every 0.5 seconds
                        Thread t = new Thread(() =>
                        {
                            while (splashrunning)
                            {
                                // If splash requests exit pull gameMode choice and IP Address before killing it, then quit this thread
                                if (splash.requestingExit)
                                {
                                    choice = splash.choice;
                                    ip = splash.ip;
                                    // The offending piece of code, without this you can simply select an option, force close and second part runs fine
                                    //splash.Exit();
                                    splashrunning = false;
                                }
                                Thread.Sleep(500);
                            }
                        });
                        t.Start();
                    }
                    splash.Run();
                }
            }
            // If splash screen is not running, assign default values
            if(!useThreading || !runSplash || ignoreThreadResponse)
            {
                choice = 2;
                ip = "127.0.0.1";
            }
            if (choice != 0)
            {
                // This game is picked up by garbage collection after running Update once
                using (Game1 game = new Game1(choice, ip))
                {
                    game.Run();
                }
            }
        }
    }
}

当调用splash.Exit()时,它会在第一次更新后收集game1。如果我禁用线程,它工作正常。如果我使用右上角的X退出它可以正常工作。如果启用了线程,我是否忽略了线程响应,游戏无法运行,我调用了splash.Exit()。

我正在寻找的是以下任何一种:

  • 收集第二场比赛的原因。

  • 退出游戏或调用“关闭窗口”(大红色x)功能的另一种方法。

  • 实现此目的的更好方法。

我过去曾使用控制台输入执行此操作,但我想继续使用图形界面而不是用户的丑陋命令提示符。

修改:
事实证明我几乎就在那里。虽然GSM可能是正确的做事方式,但对于那些只想从问题中获取代码并谨慎对待风的人来说,你只需要添加一个线程来运行第二场游戏。 我很确定这不太理想,但在我的情况下调整的次数要少得多。

Thread gt = new Thread(() =>
{
    using (Game1 game = new Game1(choice, ip))
    {
        game.Run();
    }
});
gt.Start();

因此,虽然我建议任何人从头开始使用GSM,但这可能是其他人试图让它运行的快速解决方案。

1 个答案:

答案 0 :(得分:1)

您的Splash课程是什么样的? Exit是Game类的一种方法,并退出游戏。您的Splash类是继承Game吗?如果是这样,那就不应该。

修改

更清楚地阅读帖子的下半部分后 - 你应该只有一个继承自Game的类,它应该运行你的游戏。如果要显示启动画面,它应该是自定义类,或者查看Game State Management示例。