|
-
Apr 5th, 2017, 10:21 AM
#1
Thread Starter
New Member
Updating text app freezes
Hi all I have a asyncronis server and on response I need to update texbox1 with it I googled and found out that you need a delegate sub I added it in several different ways but each time the program becomes unresponsive not sure what I am doing wrong it doesn't throw any errors.
Code:
Delegate Sub SetTextCallback([text] As String)
Private Sub SetText(ByVal [text] As String)
' InvokeRequired required compares the thread ID of the
' calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.TextBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {[text]})
Else
Me.TextBox1.Text = [text]
End If
End Sub
Public Sub ReadCallback(ByVal ar As IAsyncResult)
Dim content As String = String.Empty
' Retrieve the state object and the handler socket
' from the asynchronous state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim handler As Socket = state.workSocket
' Read data from the client socket.
Dim bytesRead As Integer = handler.EndReceive(ar)
'Dim NewByte() As Byte = state.buffer.Reverse
If bytesRead > 0 Then
Dim ByteArray(256) As Byte
Dim i As Integer = 0
For Each Byte0 As Byte In state.buffer
If Byte0 > 0 Then
ByteArray(i) = Byte0
i += 1
End If
Next
' There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(ByteArray, 0, bytesRead).Trim(Chr(0)).ToString())
End If
' Check for end-of-file tag. If it is not there, read
' more data.
content = state.sb.ToString()
If content.EndsWith("<EOF>") Then
Dim response As String = content
response = content.Remove(0, 1)
response = response.Replace("<EOF>", "").Trim
'Gets to here invoke is required and app just freezes with no eerors
If TextBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
TextBox1.Invoke(d, New Object() {TextBox1})
Else
TextBox1.Text = Text
End If
Else
' Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
End If
'
End Sub 'ReadCallback
-
Apr 5th, 2017, 10:28 AM
#2
Re: Updating text app freezes
Normally, when you get an unresponsive app, it is caused by one of two conditions: Either it's an infinite loop (which seems unlikely in this case), or the program is deadlocked (which seems more likely in this case). You can determine which of the two it is, usually, by hitting the Pause button in the IDE when the program is frozen. In most cases, you will be taken to a line of code. If you then press F11 and nothing happens, you are deadlocked, and the line of code you are on is strongly related to the problem, or is the problem. If you press F11 and you step forwards to the next line, then you're in an infinite loop.
However, in this case, it's also possible that you will be taken to a screen saying No Source Code Available. That would be unfortunate, but the test is a good one. If you find that you are deadlocked, which line is it stuck on?
My usual boring signature: Nothing
 
-
Apr 5th, 2017, 10:46 AM
#3
Thread Starter
New Member
Re: Updating text app freezes
Good call I didn't realize the pause button thing. I found the app freezes long before that. On starting the server its stuck in loop not sure why? Cant it listen without freezing the form?
Code:
Sub ServerStart()
' Data buffer for incoming data.
Dim bytes() As Byte = New [Byte](1023) {}
' Establish the local endpoint for the socket.
Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
Dim ipAddress As IPAddress = GetLocalIP()
Dim localEndPoint As New IPEndPoint(ipAddress, 9001)
' Create a TCP/IP socket.
Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
' Bind the socket to the local endpoint and listen for incoming connections.
listener.Bind(localEndPoint)
listener.Listen(100)
TextBox1.Text = "Listening" & Environment.NewLine
While True
' Set the event to nonsignaled state.
allDone.Reset()
' Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...")
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
' Wait until a connection is made and processed before continuing.
''Here is where it waits for a connection but why cant I even move my form
allDone.WaitOne()
End While
End Sub
-
Apr 5th, 2017, 10:49 AM
#4
Re: Updating text app freezes
inside the ReadCallback, change this :
Code:
If TextBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
TextBox1.Invoke(d, New Object() {TextBox1})
Else
TextBox1.Text = Text
End If
with
The SetText already does the check for an invoke and does so if it needs to... so there shouldn't be a reason to do it outside.
Also, shouldn't that have been Text and not TextBox1 ... that might actually be the reason there... you're passing the TEXTBOX to SetText and not the Text, which is probably causing a hidden error of somekind on the backside of the call.
-tg
-
Apr 5th, 2017, 10:53 AM
#5
Re: Updating text app freezes
you posted while I was posting, so my previous post may or may not be relevant now.
 Originally Posted by dwains
Good call I didn't realize the pause button thing. I found the app freezes long before that. On starting the server its stuck in loop not sure why? Cant it listen without freezing the form?
Code:
Sub ServerStart()
' Data buffer for incoming data.
Dim bytes() As Byte = New [Byte](1023) {}
' Establish the local endpoint for the socket.
Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
Dim ipAddress As IPAddress = GetLocalIP()
Dim localEndPoint As New IPEndPoint(ipAddress, 9001)
' Create a TCP/IP socket.
Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
' Bind the socket to the local endpoint and listen for incoming connections.
listener.Bind(localEndPoint)
listener.Listen(100)
TextBox1.Text = "Listening" & Environment.NewLine
While True
' Set the event to nonsignaled state.
allDone.Reset()
' Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...")
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
' Wait until a connection is made and processed before continuing.
''Here is where it waits for a connection but why cant I even move my form
allDone.WaitOne()
End While
End Sub
What you have there is a busy wait cycle... what you should be doing is setting up the listener and then waiting for the BeginConnection event (or what ever event is fired when a client connects) ... Right now on the UI thread, you're waiting for a connection... it's essentially a data stream version of displaying a for using ShowDialog... everything stops until the condition is met. That's why you should be using the events that fire when a connection is made... THEN you can proceed.
-tg
-
Apr 5th, 2017, 10:55 AM
#6
Thread Starter
New Member
Re: Updating text app freezes
Being as I need the textbox1 to display the response as string shouldn't it be like so?
Code:
Dim response As String = content
response = content.Remove(0, 1)
response = response.Replace("<EOF>", "").Trim
If TextBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
TextBox1.Invoke(d, New Object() {response})
Else
TextBox1.Text = response
End If
-
Apr 5th, 2017, 10:57 AM
#7
Thread Starter
New Member
Re: Updating text app freezes
Go figure I got the code from Microsoft website should have figured it wouldn't work out of the box lol
-
Apr 5th, 2017, 11:16 AM
#8
Re: Updating text app freezes
Strange thing from an MS website. There's a TCPListener class that wraps a socket, so MS generally discourages people to work with a raw socket the way you are. Still, once you start a TCPListener, you can call AcceptSocket, but that will block until a connection request is received, so you'd have to be doing that on a background thread. It is pretty efficient to have a method block in that fashion, as it will only do something as needed, but whatever thread it is on will be essentially sleeping until a connection comes in, so the thread will appear to freeze.
My usual boring signature: Nothing
 
-
Apr 5th, 2017, 11:32 AM
#9
Thread Starter
New Member
Re: Updating text app freezes
To give you a little insight on what I am trying to accomplish I have win IoT on a raspberry pi 3 I already have a background server connected on that. I have a vb.net app that talks to that and it works. This will always be a one to one communication between the two of them. When a GPIO updates I need the background server to reply to the tablet pc (note the GPIO form and the background server are both on the raspberry pi) is there a way to set up the background server to keep the client as a constant so I can send data internally to the server to send data from the GPIO form to the tablet pc without setting up a extra client on the Raspberry and a extra server on the tablet PC?. I think if I send the data internally the endpoint(Client) Changes. Any thoughts on this? If you would like to see the GPIO sample code I can post it for you
Last edited by dwains; Apr 5th, 2017 at 11:34 AM.
Reason: added comment
-
Apr 5th, 2017, 11:56 AM
#10
Thread Starter
New Member
Re: Updating text app freezes
I decided to post the code as it may help. Ultimately I need the GPIO code to send status to the background server and have the background server sent it to the tablet PC. Or will I need to include a separate client on the raspberry and a separate sever on the tablet to set up 2 way communication.
GPIO code still on the Win IoT but uses a XAML form boths apps are running on Raspberry pi 3
Code:
Private Sub buttonPin_26_ValueChanged(sender As GpioPin, e As GpioPinValueChangedEventArgs)
If InManualMode = True Then Exit Sub
'' toggle the state of the LED every time the button is pressed
' need to invoke UI updates on the UI thread because this event
' handler gets invoked on a separate thread.
'The timer will track the amount of time that button Or relay Is on And display it in the textbox
Dim task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
If e.Edge = GpioPinEdge.FallingEdge Then
PartCount += 1
txtCurPartCount.Text = PartCount.ToString
GpioStatus.Text = "Screw Rotate Pressed"
elpScrewRotate.Fill = greenBrush
SRotateStartTime = DateTime.Now
ScrewRotate = True
Else
GpioStatus.Text = "Screw Rotate Released"
elpScrewRotate.Fill = redBrush
Dim duration As TimeSpan = DateTime.Now - SRotateStartTime
txtRotateTime.Text = duration.TotalSeconds.ToString("n2")
TheInjectionTime = duration.TotalSeconds.ToString("n2")
ScrewRotate = False
End If
'How can I send this to the background server without adding a client?
End Sub)
End Sub
'Win IoT Backgroung socket server the first code starts the background server and the socket server handles the rest
Code:
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Net.Http
Imports Windows.ApplicationModel.Background
Imports Windows.System.Threading
Imports TTRasberry.MainPage
' The Background Application template is documented at http://go.microsoft.com/fwlink/?LinkID=533884&clcid=0x409
'Namespace ServerSocket
Public NotInheritable Class StartupTask
'Implements IBackgroundTask
'private TTRasberry.MainPage TraspXaml;
Private socket As SocketServer
Public Shared Property DataToSend As String
Public Async Sub Run(taskInstance As BackgroundWorker)
'
' TODO: Insert code to perform background work
'
' If you start any asynchronous methods here, prevent the task
' from closing prematurely by using BackgroundTaskDeferral as
' described in http://aka.ms/backgroundtaskdeferral
'
taskInstance.RunWorkerAsync()
socket = New SocketServer(9000)
Await ThreadPool.RunAsync(Sub(x)
AddHandler socket.OnError, AddressOf socket_OnError
AddHandler socket.OnDataRecived, AddressOf Socket_OnDataRecived
socket.Start()
End Sub)
End Sub
'Private Sub IBackgroundTask_Run(taskInstance As IBackgroundTaskInstance) Implements IBackgroundTask.Run
' Throw New NotImplementedException()
'End Sub
Private Sub Socket_OnDataRecived(data As String)
Dim msg As String = "No Data"
'/here is where the data is received so do some work here
'/send the current data to the tablet for processing
If data = "SendData" Then
'sends updated data to tablet for processing
msg = DataToSend
End If
socket.Send(msg.Trim)
'/reset all paramters on Raspberry Pi
If (data.StartsWith("ResetData")) Then
'TraspXaml.InitGPIO()
End If
'
If (data.StartsWith("ServerIP")) Then
'TraspXaml.InitGPIO()
End If
End Sub
Private Sub socket_OnError(message As String)
End Sub
Code:
Imports System.Diagnostics
Imports Windows.Networking.Sockets
Imports Windows.Storage.Streams
Imports TTRasberry.MainPage
Imports System.Text
Imports System.Net.Sockets
'Namespace ServerSocket
Public Class SocketServer
'Private TraspXaml As MainPage
Private ReadOnly _port As Integer
'Public Event(MessageFromControl, addressf(send))
Public ReadOnly Property Port() As Integer
Get
Return _port
End Get
End Property
Private listener As StreamSocketListener
Private _writer As DataWriter
Public Delegate Sub DataRecived(data As String)
Public Event OnDataRecived As DataRecived
Public Delegate Sub [Error](message As String)
Public Event OnError As [Error]
Public Shared ClientIP As String
Public Property MessageToSend As String
Public Sub New(port As Integer)
_port = port
End Sub
Public Async Sub Start()
Try
'Fecha a conexão com a porta que está escutando atualmente
If listener IsNot Nothing Then
Await listener.CancelIOAsync()
listener.Dispose()
listener = Nothing
End If
'Criar uma nova instancia do listerner
listener = New StreamSocketListener()
'TraspXaml.elpServerON
'Adiciona o evento de conexão recebida ao método Listener_ConnectionReceived
AddHandler listener.ConnectionReceived, AddressOf Listener_ConnectionReceived
'Espera fazer o bind da porta
Await listener.BindServiceNameAsync(Port.ToString())
Catch e As Exception
'Caso aconteça um erro, dispara o evento de erro
RaiseEvent OnError(e.Message)
End Try
End Sub
Private Async Sub Listener_ConnectionReceived(sender As StreamSocketListener, args As StreamSocketListenerConnectionReceivedEventArgs)
Dim reader = New DataReader(args.Socket.InputStream)
_writer = New DataWriter(args.Socket.OutputStream)
Try
While True
Dim sizeFieldCount As UInteger = Await reader.LoadAsync(4)
'Caso ocora um desconexão
If sizeFieldCount <> 4 Then
Return
End If
'Tamanho da string
'Dim stringLenght As UInteger = reader.ReadUInt32()
Dim stringLenght As UInteger = reader.ReadUInt32()
'Ler os dados do InputStream
Dim actualStringLength As UInteger = Await reader.LoadAsync(stringLenght)
'Caso ocora um desconexão
If stringLenght <> actualStringLength Then
Return
End If
'Dispara evento de dado recebido
'If OnDataRecived IsNot Nothing Then
'Le a string com o tamanho passado
Dim data As String = reader.ReadString(actualStringLength)
Dim GetIP() As String = data.Split(" : ")
ClientIP = GetIP(0).Trim
data = GetIP(2).Trim
'Dispara evento de dado recebido
RaiseEvent OnDataRecived(data)
Debug.WriteLine(data)
'End If
End While
Catch ex As Exception
' Dispara evento em caso de erro, com a mensagem de erro
RaiseEvent OnError(ex.Message)
End Try
End Sub
Public Async Sub Send(message As String)
If _writer IsNot Nothing Then
'Envia o tamanho da string
_writer.WriteUInt32(_writer.MeasureString(message))
'Envia a string em si
_writer.WriteString(message)
Try
'Faz o Envio da mensagem
Await _writer.StoreAsync()
'Limpa para o proximo envio de mensagem
Await _writer.FlushAsync()
Catch ex As Exception
RaiseEvent OnError(ex.Message)
End Try
End If
End Sub
End Class
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|