Help wanted with refreshing the UI..Its hanging!!!

calvin_nr

Member
Joined
Oct 1, 2007
Messages
5
Programming Experience
1-3
Hi guys. I am new to this place and find it to be wonderful.

I have implemented a client and server application in VB.net. Everything is working fine. The Server is a multi threaded server. The server process has a form where I have a rich text box which will display client information regarding who have connected to my server. But this form when executed, kind of "hangs" when executing. It doesn't show the form contents. Instead the whole form goes blank just like when an application hangs. I have to find a way to display information on this form when ever connections happen but this is not happening.:mad:

Please help me out...I want the form to refresh and show the information when users connect to the server. This is my code.......

VB.NET:
Imports System.Net.Sockets
Imports System.Text
Imports System.Net
Imports System.IO
Imports System.Data.OleDb

Public Class Server

    Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
       

    End Sub


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


    End Sub

    Private Sub RichTextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RichTextBox1.TextChanged

    End Sub

    Private Sub InitializeServer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InitializeServer.Click
        ' Must listen on correct port- must be same as port client wants to connect on.
        'Const portNumber As Integer = 8000
        Form2.Show()
        Dim Listener As TcpListener
        Dim ClientNum As Integer
        Dim port As Int32 = 8000
        Dim localAddr As IPAddress = IPAddress.Parse("129.107.62.231")


        'Dim tcpListener As New TcpListener(portNumber)
        Application.DoEvents()
        Listener = New TcpListener(localAddr, port)

        Listener.Start()
        Console.WriteLine("Waiting for connection...")
        Form2.RichTextBox1.Text = "Waiting for connection..."
        Do
            Try
                'Accept the pending client connection and return 
                'a TcpClient initialized for communication. 
                Dim tcpClient As TcpClient = Listener.AcceptTcpClient()
                ' Console.WriteLine("Connection accepted.")
                RichTextBox1.Text = "Connection accepted."
                ClientNum += 1

                Dim Handler As New ClientHandler(tcpClient, "Client" & ClientNum.ToString())

                Dim HandlerThread As New System.Threading.Thread(AddressOf Handler.start)

                HandlerThread.IsBackground = True
                Application.DoEvents()
                HandlerThread.Start()

            Catch err As Exception
                Console.WriteLine(err.ToString())

            End Try
        Loop
    End Sub
End Class
Public Class ServerMessages
    Public Const acknowledgeOK As String = "OK"
    Public Const acknowledgeCancel As String = "Cancel"
    Public Const Disconnect As String = "Bye"
End Class
Public Class ClientMessages
    Public Const RequestConnect As String = "Hello"
    Public Const Disconnect As String = "Bye"
End Class

Public Class ClientHandler
    Private Client As TcpClient
    Private ID As String
    Public Sub New(ByVal Client As TcpClient, ByVal ID As String)
        Me.Client = client
        Me.ID = ID

    End Sub
    Public Sub start()
        Dim Stream As NetworkStream = Client.GetStream()

        Dim w As New BinaryWriter(Stream)

        Dim r As New BinaryReader(Stream)

        'Dim str As String = r.ReadString().ToString()

        If r.ReadString() = ClientMessages.RequestConnect Then
            w.Write(ServerMessages.acknowledgeOK)
            'Console.WriteLine(ID & " : Connection completed")
            Application.DoEvents()
            Server.RichTextBox1.Text = ID & " : Connection completed"
            'provider to be used when working with access database
            Dim cn As OleDbConnection

            Dim cmd As OleDbCommand

            Dim dr As OleDbDataReader

            
            Do
                Dim str As String = r.ReadString()
                Dim str1 As String
                If (str = ClientMessages.Disconnect) Then
                    Console.WriteLine(ID & " :Disconnect request received")
                    w.Write(ServerMessages.Disconnect)
                Else
                    Dim sqlQueryStr As String = str
                    'Creates the OLEDB connection to the thesaurus database
                    cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\crn8539\My Documents\NEW_PROJECT\db1.mdb;")
                    cn.Open()
                    'Obtain the other meanings of the word passed by the client'
                    cmd = New OleDbCommand("select * from thesaurus where keyword ='" & sqlQueryStr & "'", cn)
                    dr = cmd.ExecuteReader
                    While dr.Read()
                        'Console.WriteLine(dr(0))
                        'Form1.TextBox1.Text = dr(0)
                        str1 = dr(1) + ";" + dr(2) + ";" + dr(3) + ";" + dr(4)
                        w.Write(str1)
                    End While

                    Console.WriteLine(str)
                End If
                'Loop
            Loop Until r.ReadString() = ClientMessages.Disconnect
            'Console.WriteLine(ID & " :Disconnect request received")
            'w.Write(ServerMessages.Disconnect)
        Else
            Console.WriteLine(ID & ":Connection could not be completed")
        End If

        Client.Close()

        'Console.WriteLine(ID & " :Connection Closed")
        Application.DoEvents()
        Server.RichTextBox1.Text = ID & " :Connection Closed"
        ' pause so user can view the console output
        Console.ReadLine()
    End Sub
End Class
Thank you all in advance
 
You have an endless loop in InitializeServer_Click tying your UI thread. Do the accepting loop in a thread of its own. Also you have to find out how to access a control from a different thread.
 
Thanks john but can u be a little more specific....If I remove the loop how will I achieve the looping functionality? :confused:
 
You must use threads. Threads are like independant programs that can hang without affecting your main application. It is a very large subject, but you should be able to find out enough about it by googling "Thread"...
 
Calvin.

Put a BackgroundWorker on your form. In the DoWork event handler is where you should move all your socket accept code.

When you want to update the ui, you MUST NOT do it in the DoWork() event handler because thats running a different thread. Instead, call BackGRoundWorker.ReportProgress(0, "pass in your message here") and in the ProgressCHanged() event handler, update the UI there.


Basically all that code in InitializeServer_Click should be the DoWOrk() of the backgroundworker.
InitServer_CLick code should merely be something like:

If Not bgw.IsBusy Then bgw.RunWorkerAsync()


That starts the listening.

Remember, all code that accesses a UI control MUST NOT be called from DoWork() because it will cross-thread hang. You MUST formulate a message in DoWork, and call ReportProgress with the message. In the ProgressChanged event, you access the e.UserState event object and that is the message you formed:

VB.NET:
Sub bgw_DoWork Handles bgw.DoWOrk
  Do
    socket.Accept()
    bgw.ReportProgress(0, "a client cnnected at" & datetime.Now)
  Loop
End SUb

Sub bgw_ProgChg(e as eventObjectThing) Handles bgw.ProgressCHanged
  MessageBox.Show(e.UserState.ToString())
End SUb
 
Back
Top