[C#] Programmet avslutas rakt av utan något felmeddelande?

Permalänk
Medlem

[C#] Programmet avslutas rakt av utan något felmeddelande?

Hej!
Som titel säger, mitt program avslutas helt tvärt utan något felmeddelande, t.ex Index out of bounds etc..

Vad programmet gör är att sparar class objekt i en lista.
Listan har en socket i varje class objekt som den håller.

Problemet uppstår bara om denna situation uppstår:
Klient 1 2 3 4 är anslutna.
Jag stänger ner klient 3 så enbart 1 2 4 är anslutna,
Klient 3 tas bort från listan.
DÅ stängs programmet tvärt utan något felmeddelande.

Men kör jag med denna metoden:
Klient 1 2 3 4 är anslutna.
Jag stänger ner klienterna i ordningen som dom anslöt, dvs 4 3 2 1, programmet fungerar som det ska och dom tas bort ur listan.

Jag har försökt leta efter vart det kraschar med att sätta breakpoints och där det kraschar kommenterar jag bort, då är det nästan grej som gör att programmet kraschar, så jag vet inte vart jag ska börja?

All kod som används (En hel del):

delegate void AddClientCallback(String pName); delegate void UpdateLogCallback(String strData); delegate void UpdateClientCallback(); public void UpdateLog(String strData) { if (this.txtDataLog.InvokeRequired) { UpdateLogCallback d = new UpdateLogCallback(UpdateLog); this.Invoke(d, new object[] { strData }); } else { txtDataLog.AppendText(strData + "\n"); } } public void UpdateClientList() { if (this.lstClients.InvokeRequired) { UpdateClientCallback d = new UpdateClientCallback(UpdateClientList); this.Invoke(d); } else { lstClients.Items.Clear(); if (playerList.Count > 0) { for (int i = 0; i < playerList.Count; i++) { AddClient(playerList[i].GetName()); } } } } private void AddClient(String pName) { if (this.lstClients.InvokeRequired) { AddClientCallback d = new AddClientCallback(AddClient); this.Invoke(d, new object[] { pName }); } else { this.lstClients.Items.Add(pName); } } public void OnClientConnect(IAsyncResult asyn) { try { Player tmpPlayer = new Player(); tmpPlayer.SetName("Player" + playerList.Count.ToString()); tmpPlayer.IsMoving = false; tmpPlayer.SetPosition(0, 0, world); tmpPlayer.playerSocket = m_mainSocket.EndAccept(asyn); tmpPlayer.PlayerID = playerList.Count; playerList.Add(tmpPlayer); WaitForData(tmpPlayer.playerSocket, tmpPlayer.PlayerID); AddClient(tmpPlayer.GetName()); UpdateLog(tmpPlayer.GetName() + " connected to the server."); m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); } catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); } catch (SocketException ex) { //MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); UpdateLog("ERROR: " + ex.ToString()); } } public void WaitForData(Socket sock, int playerID) { try { if (pfnWorkerCallBack == null) { pfnWorkerCallBack = new AsyncCallback(OnDataReceived); } SocketPacket theSockPacket = new SocketPacket(); theSockPacket.m_currentSocket = sock; theSockPacket.playerID = playerID; sock.BeginReceive(theSockPacket.dataBuffer, 0, theSockPacket.dataBuffer.Length, SocketFlags.None, pfnWorkerCallBack, theSockPacket); } catch (SocketException ex) { //MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); UpdateLog("ERROR: " + ex.ToString()); } } public void OnDataReceived(IAsyncResult asyn) { int pID = 0; try { SocketPacket socketData = (SocketPacket)asyn.AsyncState; pID = socketData.playerID; int iRx = 0; iRx = socketData.m_currentSocket.EndReceive(asyn); char[] chars = new char[iRx + 1]; Decoder d = Encoding.UTF8.GetDecoder(); int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0); String szData = new String(chars); if (szData == "\n\0") { HandleData(socketData.m_currentSocket, playerList[socketData.playerID].recData, socketData.playerID); playerList[socketData.playerID].recData = ""; } else { playerList[socketData.playerID].recData += szData[0]; } WaitForData(socketData.m_currentSocket, socketData.playerID); } catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n"); } catch (SocketException ex) { UpdateLog(playerList[pID].GetName() + " disconnected from the server."); SendData("FORCEREFRESHPLAYERLIST"); playerList.RemoveAt(pID); UpdateClientList(); } }

Antingen är jag helt blind eller så är det något jag har missuppfattat! Har klurat på detta i flera dagar utan att komma vidare

//AJL

Visa signatur

C#/MonoGame Fanatiker.
Pixel Artist & Game Developer

Permalänk
Hedersmedlem

Att använda playerID som index i listan fungerar väl inte så bra för utom just i det där fallet som fungerar. Om till exempel klient 0 försvinner finns {1, 2, 3} kvar, men om sedan klient 3 kopplar ned försöker man ta bort element 3...

Du kan för övrigt få koden lite läsligare genom att ersätta

if (this.txtDataLog.InvokeRequired) { UpdateLogCallback d = new UpdateLogCallback(UpdateLog); this.Invoke(d, new object[] { strData }); } else { txtDataLog.AppendText(strData + "\n"); }

och liknande med

txtDataLog.Invoke(new MethodInvoker(delegate { txtDataLog.AppendText(strData + "\n"); }));

(en av tjusningarna med c# framför c++/cli är anonyma delegatfunktioner)

Permalänk
Avstängd
Skrivet av Elgot:

och liknande med

txtDataLog.Invoke(new MethodInvoker(delegate { txtDataLog.AppendText(strData + "\n"); }));

(en av tjusningarna med c# framför c++/cli är anonyma delegatfunktioner)

Använder du sedan lambda blir det ännu mer cleant, sedan är nästa steg att sluta helt fulkodan sådär och använda ett MVVM ramverk...

edit: jag ser nu att du blandar socketkod och vykod.. Tror nog du inte riktigt är redo för MVVM... :/

Visa signatur
Permalänk
Medlem

Elgot:
hmm där sa du något, blir att ändra lite se om det blir nå bättre
blir att återkomma

Cyber:
Men MVVM är väl lite mysko också om jag inte missminner mig så blir MVVM extremt otympligt vid större applikationer?
Och mindre applikationer är det lite "overkill"

Visa signatur

C#/MonoGame Fanatiker.
Pixel Artist & Game Developer

Permalänk
Medlem
Skrivet av AJL:

Elgot:
hmm där sa du något, blir att ändra lite se om det blir nå bättre
blir att återkomma

Cyber:
Men MVVM är väl lite mysko också om jag inte missminner mig så blir MVVM extremt otympligt vid större applikationer?
Och mindre applikationer är det lite "overkill"

Det beror helt på hur du använder det. Det största problemet med MVVM är att många går in för hårt på "best practice" och på grund utav det helt enkelt gör många onödiga omvägar. Det krävs också mycket kunskap runt WPF och diverse tekniker för att man ska kunna implementera allt smidigt.

Däremot är MVVM helt fantastiskt, speciellt när det gäller större applikationer. Men det gäller att man verkligen använder MVVM för rätt orsaker. Det som gör det så enormt på företaget jag jobbar på är att man kan separerar användar gränsnittet med koden nästan helt. Det gör att vi kan testa det mesta genom "Unit Testing" och slipper hålla på att klicka runt för att försöka hitta buggar. På så sätt kan man byta ut hela sektioner av programmet och vara säker på att man inte ställt till problem med andra delar.
http://en.wikipedia.org/wiki/Unit_testing

Sedan tror det är viktigast att man bygger upp riktigt struktur som andra programmerare redan känner till. Detta gör att koden blir lättare att sätta sig in i när det behövs. Men däremot behöver det inte vara just MVVM man använder.

Permalänk
Avstängd
Skrivet av AJL:

Elgot:
hmm där sa du något, blir att ändra lite se om det blir nå bättre
blir att återkomma

Cyber:
Men MVVM är väl lite mysko också om jag inte missminner mig så blir MVVM extremt otympligt vid större applikationer?
Och mindre applikationer är det lite "overkill"

Nej, det är just vid stora enterprise applikationer som det är så viktigt att köra MVVM för att systemet ska bli ska bli skal- och förvaltningsbart. Även mindre appar blir bättre och kan dra fördel av det, du kör dock winforms, vet inte om det finns nått vettigt ramverk för det, men du borde rätt enkelt kunna byta till WPF där har du Caliburn micro som är ett grymt ramverk

Visa signatur