Toon posts:

[C#] Programma gebruikt 100 % CPU

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hmmz, ik heb een beetje een vaag probleem met een programma wat ik aan het schrijven ben. Het gaat hier om een server, en ik heb een aparte thread gemaakt waarin gewacht wordt op een verbinding. De void die ik hiervoor gebruik ziet er zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void StartServer() 
{
    try 
    {
        InterlinkXPServer = new TcpListener(ServerSettings.ServerPort);
        InterlinkXPServer.Start();
        while (true) 
        {
            TcpClient tempClient = InterlinkXPServer.AcceptTcpClient();
            int newid = Connections.Add(new Connection(tempClient, this));
        }
    }
    catch (System.Exception) 
    {
        foreach (Connection con in Connections) 
        {
             Connections.Remove(con);
             con.Dispose();
        }
        return;
    }
}

De thread blokkeert bij de regel TcpClient tempclient = InterlinkXPServer.AcceptTcpClient(). De thread doet hier dus niets totdat er een verbinding gemaakt wordt. De eerste keer gaat dit goed. Maar als er dan een verbinding gemaakt wordt en het programma komt wederom weer bij die regel, dan gebruikt het programma opeens 100% CPU. Het maffe is dus dat het de eerste keer wel goed gaat, en de tweede keer niet. Overigens gaat het in een andere thread die simultaan loopt wel goed. De void daarvoor ziet er zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void StartManagement() 
{
    try 
    {
        InterlinkXPManagement = new TcpListener(ServerSettings.ManagementPort);
        InterlinkXPManagement.Start();
        while (true) 
        {
            TcpClient tempClient = InterlinkXPManagement.AcceptTcpClient();
            Connections.Add(new ManagementConnection(tempClient, this));
        }
    }
    catch (System.Exception)
    {
        foreach (ManagementConnection con in Connections)
        {
            con.CloseConnection();
            Connections.Remove(con);
            con.Dispose();
        }
        return;
    }
}

Hier gaat het dus wel goed, en gebruikt het programma niet 100% cpu nadat er een client een verbinding heeft gemaakt. Iemand een idee hoe dat komt?

  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

code:
1
2
3
4
5
        while (true) 
        {
            TcpClient tempClient = InterlinkXPServer.AcceptTcpClient();
            int newid = Connections.Add(new Connection(tempClient, this));
        }

Wat er fout gaat is wel duidelijk. AcceotTcpClient() blockt zolang er geen clients zijn, niet zolangs er geen nieuwe clients zijn. Zodra er dus 1 client is, komt hij in een while(true) loop terecht, waarin hij je huidige client voortdurend toevoegt met Connections.Add(...)

Hoe je het op moet lossen is even lastig. Waarschijnlijk kun je gewoon checken op .Pending(), maar dat weet ik niet zeker.

Verwijderd

Op vrijdag 26 april 2002 14:08 schreef Poohbear het volgende:

...kun je gewoon checken op .Pending(), maar dat weet ik niet zeker.
Ja, dat is zo. En ik weet het wel zeker 8-)

Verwijderd

Topicstarter
Probleem is dus dat als ik er de volgende code van maak het programma ook 100 % cpu gebruikt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private void StartServer() 
{
    try 
    {
        InterlinkXPServer = new TcpListener(ServerSettings.ServerPort);
        InterlinkXPServer.Start();
        while (true) 
        {
            if (InterlinkXPServer.Pending() == true)
            {
                TcpClient tempClient = InterlinkXPServer.AcceptTcpClient();
                int newid = Connections.Add(new Connection(tempClient, this));
            }
            Thread.Sleep(500);
        }
    }
    catch (System.Exception) 
    {
        foreach (Connection con in Connections) 
        {
            Connections.Remove(con);
            con.Dispose();
        }
        return;
    }
}

Ennuhm, als dat inderdaad het probleem is, waarom werkt het bij die andere Thread dan wel goed?

Trouwens, als AcceptTcpClient alleen blockt zolang er geen nieuwe clients zijn hoe weet je dan dat je de goede client te pakken hebt als je die method gebruikt? Overigens blokkeert hij wel weer op die call, want als ik er een breakpoint neerzet en dan op F11 druk dan gaat het programma verder met uitvoeren, en gebeurdt er niets totdat er weer een client connect.

Verwijderd

Normaliter spawn je een nieuwe thread voor de handling van een request. Je hebt dus een thread die als gatekeeper optreedt en wacht op een nieuwe connection. (je 1e stuk code). Zodra een connection binnenkomt, creeer je een nieuwe thread en daar geef je de connection aan door. Je duikt dan weer in de wachtmode voor de volgende connection.

Ga je alles in dezelfde thread doen, dan wordt het onbeheersbaar. Ik heb nog geen ervaring met profiling in C#, maar weet je zeker dat de cpu rondholt in die while loop?

Verwijderd

Topicstarter
Hmmz, volgens mij loopt ie toch echt vast op die AcceptTcpClient regel, omdat als het programma voor de tweede keer daar is opeens het processor gebruik naar 100% stijgt.

Verwijderd

Topicstarter
Hmmz, in de Connection class wordt een nieuwe thread gemaakt om te kijken of er data is om te lezen. Dus het loopt niet allemaal in dezelfde thread.

Verwijderd

Topicstarter
Hmmz, het probleem bleek dus te zitten in de Thread die de data uit leest. Ik had hier geen Thread.Sleep() in gezet, waardoor die Thread dus m'n hele CPU in gebruik nam. Mooi, weer een bugje gefixed, hehe, we proggen lekker verder.
Pagina: 1