【问题标题】:XNA game collected by GC after running update运行更新后 GC 收集的 XNA 游戏
【发布时间】:2012-03-10 22:49:56
【问题描述】:


我正在编写一个返回游戏模式 (int) 和 IP 地址 (string) 的启动画面。这个想法是启动画面运行,接受用户输入,然后使用这些选项运行主游戏。我正在使用一个线程来实现这一点 - 线程从启动屏幕轮询退出请求,然后将值拉出到 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,但对于其他试图使其运行的人来说,这可能是一个快速的解决方案。

【问题讨论】:

    标签: c# multithreading garbage-collection xna


    【解决方案1】:

    您的Splash 班级是什么样的? Exit是Game类的方法,退出游戏。您的Splash 类是否继承Game?如果是这样,它不应该。

    编辑:

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

    【讨论】:

    • 感谢您的回复,是的,它们都继承自 Game。是否有任何技术/设计原因导致这是不好的做法,或者仅仅是因为这样的故障?我问是因为没有额外的线程它可以正常工作。
    • 我应该澄清一下——当我说“故障”时,我主要是指我自己缺乏知识。我的理由是从 Game 继承的 2 个不同的类应该只创建 2 个不同的游戏。如果有人有理由摧毁一个摧毁另一个,我想听听,但我有一个答案,并将研究 GSM 作为一个选项,将问题标记为已回答。
    • 在几乎所有情况下,当你制作一个游戏时,你就是在制作一个游戏。 Game 类旨在运行您的游戏。那么为什么你会拥有不止一个呢? XNA 框架是根据该假设设计的,因此除其他外,这意味着,当您Exit() 游戏时,您将退出游戏应用程序。 Game 类还处理图形设备,并且该资源一次只能由一个“游戏”拥有。游戏循环也由 Game 类处理,因此您会遇到多个实例的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 2013-01-04
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    相关资源
    最近更新 更多