【问题标题】:While(true) loop making my program not start upWhile(true) 循环使我的程序无法启动
【发布时间】:2012-04-07 21:38:40
【问题描述】:

我正在尝试制作一个使用 XNA 的 SteamRE 机器人,现在,我刚刚创建了一个新的 XNA 项目,并在上面添加了 SteamRE 示例代码,如果我运行它,它工作正常,但问题是,它实际上并没有启动 XNA 窗口,因此它无法查找键盘处理等。

如果我删除 while(true) 循环,它可以工作,但不会连接。

这是我的代码,如果你们可以看看这个并帮助我,那就太好了。

namespace Steam
{
  public class Game1 : Microsoft.Xna.Framework.Game
  {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    string userName = "username";
    string passWord = "password";

    SteamClient steamClient = new SteamClient(); // initialize our client
    SteamUser steamUser;
    SteamFriends steamFriends;

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

    protected override void Initialize()
    {
        base.Initialize();
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);

        steamUser = steamClient.GetHandler<SteamUser>(); // we'll use this later to logon
        steamFriends = steamClient.GetHandler<SteamFriends>();

    }

    protected override void UnloadContent()
    {
    }

    KeyboardState oldState = Keyboard.GetState();

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        ConnectSteam();

        base.Update(gameTime);
    }

    public void ConnectSteam() 
    {
        steamClient.Connect(); // connect to the steam network

        while (true)
        {
            CallbackMsg msg = steamClient.WaitForCallback(true); // block and wait until a callback is posted

            msg.Handle<SteamClient.ConnectCallback>(callback =>
            {
                // the Handle function will call this lambda method for this callback

                if (callback.Result != EResult.OK)
                {
                    Console.WriteLine("Failed. 1");
                }
                //break; // the connect result wasn't OK, so something failed

                // we've successfully connected to steam3, so lets logon with our details
                Console.WriteLine("Connected to Steam3.");
                steamUser.LogOn(new SteamUser.LogOnDetails
                {
                    Username = userName,
                    Password = passWord,
                });
                Console.WriteLine("Logged on.");
            });
            msg.Handle<SteamUser.LogOnCallback>(callback =>
            {
                if (callback.Result != EResult.OK)
                {
                    Console.WriteLine("Failed. 2");
                }

                // we've now logged onto Steam3
            });
        }
    }

    public void ConnectToFPP() 
    {
        KeyboardState newState = Keyboard.GetState();  // get the newest state

        // handle the input
        if (oldState.IsKeyUp(Keys.Space) && newState.IsKeyDown(Keys.Space))
        {
            steamFriends.JoinChat(110338190871147670);
        }

        oldState = newState;  // set the new state as the old state for next time
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        base.Draw(gameTime);
    }
  }
  }

谢谢!

【问题讨论】:

  • 你使用while(true) 一个无限循环,它不仅会阻塞窗口,还会阻塞程序本身。
  • Steam 客户端可能会超时,或者您阻塞线程和设置回调的方式可能存在其他问题。是否可以创建显式超时?

标签: c# xna


【解决方案1】:

据我所知,问题在于,除非您需要不断连接,否则您需要在实际连接时中断 ConnectSteam 代码。

Console.WriteLine("Logged on.");
break;

或者,你可以有一个 isConnected 变量(非常伪代码):

bool isConnected = false
while(!isConnected)
{
    isConnected = LogonCode;

}

【讨论】:

    【解决方案2】:

    我不是 XNA 方面的专家,但我看到您在 Update() 窗口的方法中使用 while(true) 循环,该方法必须处理非场景,但窗口控制更新(实际上即使场景没有更新会从这个角度改变)。

    您在尝试连接某些服务时遇到了无限循环。您在创建窗口的同一线程上运行它,以便阻止窗口。 我建议您使用多线程,因此在您尝试连接另一个线程的地方运行代码。使用ThreadPool.QueueUserWorkItem 或其他方式运行线程并向用户提供程序正在连接的信息。

    【讨论】:

      【解决方案3】:

      正如其他人指出的那样,问题出在while(true) 片段中。即使你成功连接,你也永远不会跳出循环。即使在连接后使用break; 可以解决问题,但在建立连接之前,您仍然会阻止整个进程运行。

      最好的解决方案是删除while,并且每帧一次(或第二次,或异步调用使用的等待时间的两倍),如果连接未建立,请尝试仅一次连接再次。由于您的连接代码是异步的,您的游戏将继续循环,您可以继续在屏幕上绘制并通知用户事情进展如何。

      protected override void Update (GameTime gameTime)
      {
          // ...
          if (!connected && !tryingToConnect)
          {
              ConnectSteam();
      
              // Remember to set to false once connection is established
              showConnectingDialog = true;
          } else
          {
      
          }
          // ...
      }
      
      protected override void Draw (GameTime gameTime)
      {
          // ...
          if (showConnectingDialog)
          {
              SpriteBatch.DrawString(SpriteFont, "Connecting to Steam servers...", Vector2.Zero, Color.White);
          } else
          {
              // ...
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-01
        • 1970-01-01
        • 2018-10-28
        • 2016-12-02
        • 2015-01-19
        • 2017-07-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多