Ab und zu NullReferenceException ( List, Class )

04/23/2017 17:53 Ortator#1
Hallo,

ich bekomme ab und zu eine NullReferenceException:

Code:
    public class PlayerManager{
        public class PlayerData{
            string[] PlayerDataString = { "" };
            int[] PlayerDataInt = { 0 };
            Socket PlayerDataSocket;
            /* === PlayerDataString ===
             * [0] PlayerName
             * 
             * 
             * */
            /* === PlayerDataInt === 
             * [0] Session ID
             * 
             * */
            public void SetName(string PlayerName){this.PlayerDataString[0] = PlayerName;}
            public void SetSocket(Socket handler){this.PlayerDataSocket = handler;}
            public void SetSessionID(int SessionID){this.PlayerDataInt[0] = SessionID;}
            public Socket GetSocket(){return this.PlayerDataSocket;}
            public int GetSessionID() { return this.PlayerDataInt[0]; }
        }
        private static List<PlayerData> PlayerDataList = new List<PlayerData>();
        public static void CreatePlayerData(Socket PlayerHandler,string PlayerName,int SessionID){
            try{
                PlayerData CreateNewPlayer = new PlayerData();
                //--------------------------------------------
                CreateNewPlayer.SetName(PlayerName);
                CreateNewPlayer.SetSessionID(SessionID);
                CreateNewPlayer.SetSocket(PlayerHandler);
                //--------------------------------------------
                PlayerDataList.Add(CreateNewPlayer);
            }
            catch (Exception ex) { GameConsole.WriteConsoleGameParams(System.ConsoleColor.Red, $"ERROR GetPlayerBySocket()", ex.ToString()); }
        }
        public static PlayerData GetPlayerBySocket(Socket handler){
            PlayerData returnPlayerData = null;
            try {
                for (int i = 0; i <= PlayerDataList.Count-1; i++) {
                    if (PlayerDataList[i].GetSocket() == handler){
                        returnPlayerData = PlayerDataList[i];
                        break;
                    }
                }
                return returnPlayerData;
            }
            catch (Exception ex) { GameConsole.WriteConsoleGameParams(System.ConsoleColor.Red, $"ERROR GetPlayerBySocket()", ex.ToString()); return returnPlayerData; }
        }
    }
Hier wird sie abgefragt:

Code:
        public static void IncommingPacket(Socket handler,byte[] PacketByte){
            try{
                PlayerManager.PlayerData PacketPlayer = PlayerManager.GetPlayerBySocket(handler);
                    if (PacketPlayer.GetSessionID() == 0){
                        string SessionPacket =
GameCrypto.DecryptCustomParameter(PacketByte);
                        string[] SessionParts = SessionPacket.Split(' ');
                        if (SessionParts.Length < 2 || !SessionParts.Any()){
                            return;
                        }
                        int SessionID;
                        if (int.TryParse(SessionParts[1].Split('\\').FirstOrDefault(), out SessionID))
                        {
                            Console.WriteLine("Test .. Session hat sich verbunden: " + SessionID);
                        }
                    }
            }
            catch (Exception ex) { GameConsole.WriteConsoleGameParams(System.ConsoleColor.Red, $"ERROR IncommingPacket", ex.ToString()); }
        }
Hier kommt ab und zu der Fehler:

Code:
if (PacketPlayer.GetSessionID() == 0){
Weiss jemand woran das liegt? An sich findet es immer den Socket ( Habe mal Debug gemacht und es zeigt mir immer die zugehörige List an ( zB. 0,1,2,3... ))

Es währe halt wichtig das dieser Exception nicht kommt , weil ich zB. die Session auslesen muss falls sie 0 ist.

Danke für jeden Tipp
04/23/2017 18:53 Else#2
Die Meldung sagt dir, dass eine Variable nicht besetzt ist. Ich würde ggf. mal in den Stacktrace sehen? Schau dir mal deine Funktion GetPlayerBySocket an. Ich behaupte mal, dass er den Handler im Array nicht findet und da ja sowieso die Variable auf "null" gesetzt wird zu Anfang. Somit wäre deine PacketPlayer-Instanz in der Funktion IncommingPacket "null" und hättest demzufolge auch keine Session-ID, was dann eine NullReferenceException wirft.
04/24/2017 07:16 IceTrailer#3
Du solltest nicht ohne Abfrage auf den ersten Wert (also Index 0) deines Arrays zugreifen.
Mach davor ein Return falls die Größe des Arrays kleiner als 1 ist. Danach würde ich genau ansehen, warum der erste Wert wann nicht besetzt ist.
04/24/2017 07:30 Ortator#4
Ich probiere mal mein Glück.

MfG
04/24/2017 16:48 0x6a6b#5
Also erstens steige auf eine threadsafe collection um wenn möglich und vergiss nie deine objekte zu locken bei write access.
Sobalt du das gemacht hast: tadaa es funktioniert! Warum? Na weil du asyncron(auch wenn du es nicht wissen solltest: das system erstellt dir im hintergrund Threads) in deiner liste operierst und schreibst, das macht das ganze höchst instabil.
04/24/2017 17:50 Shawak#6
tbh kannst du das gar nicht wissen, weil dafür der Rest des Codes fehlt um eine genaue Aussage zu tätigen.
Und sogar wenn es so wäre, müsstest du auch bei einem read locken (bis auf wenige Ausnahmen).