3

I'm using the Photon server to run a multiplayer game, once in every 100+ games, the server stops responding to input -- looking at the log file I'm getting the following exception:

2013-07-30 12:31:24,918 [11] ERROR Lite.Room [(null)] - System.IndexOutOfRangeException: Index was outside the bounds of the array. at STSLib.Engine.handleInput(Hashtable input, Int32 playerId) in C:\Program Files (x86)\Photon\Photon src-server\STSServer\STSLib\Engine.cs:line 130

Looking at my code, my line 130 of my engine class is a foreach loop:

foreach (Player p in players)
{
    Queue playerQueue = new Queue();
    returnTable.Add(p.playerId, playerQueue);       
}

Where player is a class I made to represent (you guessed it!) players of the game, and players is an array of Players. returntable, is a hashtable of queues of hashtables of other data that I am sending to the clients, and I am just instantiating each key with an empty queue.

The foreach loop gets called, and works multiple times before the game gets broken in this scenario -- that is to say that this exception starts getting thrown in the middle of gameplay.

Can anyone explain how a foreach loop could ever throw an index out of bounds exception?

Jeremy Kalas
  • 114
  • 1
  • 10
  • 2
    Can you paste the whole foreach loop? – Pierre-Luc Pineault Jul 30 '13 at 16:45
  • `players` is probably an IEnumerable that hasn't been evaluated until this foreach loop. Can you should the creation of players? – Alden Jul 30 '13 at 16:45
  • Just in case it is an issue with changing your players list, you could at least try [this](http://stackoverflow.com/questions/66622/threadsafe-foreach-enumeration-of-lists) – Jwosty Jul 30 '13 at 16:50
  • With an `array` this should never happen, not even with concurrency. Be more exact about the data, types and declarations. Also specify whether you use any concurrency. – H H Jul 30 '13 at 16:50
  • Players has been instantiated -- this exception starts being thrown in the middle of gameplay -- after this loop has been run successfully several times – Jeremy Kalas Jul 30 '13 at 16:55
  • It does not matter how many times it ran OK - concurrency issues will appear randomly. – H H Jul 30 '13 at 17:02

1 Answers1

5

It should not ... unless you use concurrency and the players variable is changed elsewhere while the loop is running.

Afaik it is not possible to change players within the loop (I think you will get a runtime error on that location, but not on the foreach loop).

Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
  • or it could be lazy evaluation biting him here, like: `var players = otherPlayers.Select(x => myArray[x.Id])` – Alden Jul 30 '13 at 16:46
  • I added the full loop code. The players array does not get modified -- I'm just instantiating values for a hashtable. – Jeremy Kalas Jul 30 '13 at 16:51
  • 1
    Are you sure there is no code being ran concurrently with the code you posted? – Michel Keijzers Jul 30 '13 at 16:52
  • 1
    Its almost definitely a concurrency issue, I added some more debug statements, but this happens so infrequently, that I doubt I'll figure it out for a while. It may happen that the players array gets reset if there is a failed join attempt to the lobby, but I'll look into it, thanks for the help. – Jeremy Kalas Jul 30 '13 at 17:29
  • Maybe you can put an assertion in the loop to check if the length is correct (unchanged) and print out the list at that moment so you can check which player has been removed. – Michel Keijzers Jul 30 '13 at 21:08
  • Thats what I did, Ill be waiting for this weird bug to happen again – Jeremy Kalas Jul 31 '13 at 17:34