[socket] aktywne oczekiwanie

0

Witam! Pisze projekt oparty o architekture client-server. Napotkalem na problem z aktywnym oczekiwaniem (proces klienta pozera cale zasoby procesora :)) wiem dlaczego, ale nie wiem jak to obejsc. Mianowicie zaimplementowalem taka klase odpowiedzialna za polaczenie TCP:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Security.Principal;

namespace Client
{
    class TcpConnection
    {
        private TcpClient tcpClient;
        private IPEndPoint serverEndPoint;

        private Thread listenThread;

        public TcpConnection()
        {
            tcpClient = new TcpClient();
            serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4000);
        }

        public void Connect()
        {
            tcpClient = new TcpClient();
            try
            {
                tcpClient.Connect(serverEndPoint);
                listenThread = new Thread(new ThreadStart(Listen));
                this.listenThread.IsBackground = true;
                this.listenThread.Start();
            }
            catch(Exception e)
            {
                //System.Windows.Forms.MessageBox.Show(e.ToString());
            }
        }

        private void Listen()
        {
            NetworkStream clientStream = tcpClient.GetStream();
            byte[] message = new byte[4096];
            int bytesRead;

            while (true)
            {
                bytesRead = 0;

                try
                {
                    //blocks until a client sends a message
                    bytesRead = clientStream.Read(message, 0, 4096);
                }
                catch
                {
                    //a socket error has occured
                    break;
                }

                if (bytesRead == 0)
                {
                    //the client has disconnected from the server
                    break;
                }

                //message has successfully been received
                ASCIIEncoding encoder = new ASCIIEncoding();

                string msg = encoder.GetString(message, 0, bytesRead);
                if (msg.Contains("message"))
                {
                    System.Windows.Forms.MessageBox.Show(msg.Substring(8));
                }
            }
            tcpClient.Close();
        }

        public bool isConnected()
        {
            return tcpClient.Connected;
        }

        public void sendString(string text)
        {
            try
            {
                NetworkStream clientStream = tcpClient.GetStream();

                ASCIIEncoding encoder = new ASCIIEncoding();
                byte[] buffer = encoder.GetBytes(text);

                clientStream.Write(buffer, 0, buffer.Length);
                clientStream.Flush();
            }
            catch (Exception e)
            {
            }
        }

    }
}

oraz w glownej petli programu sprawdzam w kolko, czy mam polaczenie z serwerem, a jak go nie mam to wznawiam polaczenie:

namespace Client
{
    static class ClientProgram
    {
        [STAThread]
        static void Main()
        {          
            TcpConnection TCP = new TcpConnection();
            while (true)
            {
                while (!TCP.isConnected())
                {
                    TCP.Connect();
                }
            }
        }
    }
}

Zakladam, ze wlasnie to ciagle sprawdzanie czy jestem polaczony tak okupuje procesor. Kiedys, jak bawilem sie w starym Delphi to sockety oparte byly o eventy i nie blokowalo sie procesora.
Jakies pomysly jak mozna obejsc to aktywne oczekiwanie, albo jak zaimplementowac sockety oparte na zdarzeniach?

PS: Problem rozwiazalem w sposob dosc...nieelegancki.. utworzylem sobie nowa forme i od razu ja ukrywam, a procedure ponownego laczenia z serwerem wywoluje kiedy de facto nie jestem polaczony w osobnym watku, ale pytanie wciaz jest otwarte, bo interesuje mnie eleganckie rozwiazanie :)

0

Read na sockecie też blokuje? Mi się wydawało że Receive. A po co Ci ta pętla sprawdzająca na zewnątrz? Jak przy receive się coś wywali to masz sygnał o braku połączenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0