Multi Threading For getting links from Webbrowser1.Document - vb.net

The problem is that multi threading is not working properly for getting links from webbrowser1.document.links. How can I solve this problem?
Public Class Form1
Dim thread1 As System.Threading.Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
thread1 = New System.Threading.Thread(AddressOf GetLinks)
thread1.Start()
End Sub
Private Sub GetLinks()
For i As Integer = 0 To WebBrowser1.Document.Links.Count - 1
If TextBox1.Text.Length > 0 Then
TextBox1.Text += Environment.NewLine & WebBrowser1.Document.Links(i).ToString
Else
TextBox1.Text = WebBrowser1.Document.Links(i).ToString
End If
Next
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate("www.google.com")
Me.CheckForIllegalCrossThreadCalls = False
End Sub
End Class

You can't make a call to one of the controls on the form (in this case, TextBox1 and WebBrowser1) from another thread other than the main thread of the form. You need to use a delegate.
This will do the trick:
Private _iLinks As Integer
Dim thread1 As System.Threading.Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
CheckForIllegalCrossThreadCalls = False
_iLinks = WebBrowser1.Document.Links.Count
thread1 = New System.Threading.Thread(AddressOf GetLinks)
thread1.Start()
End Sub
Private Sub GetLinks()
For i As Integer = 0 To _iLinks - 1
UpdateTextBoxDelegate(i)
Next
End Sub
Private Sub UpdateTextBox(ByVal iLink As Integer)
If TextBox1.Text.Length > 0 Then
TextBox1.Text += Environment.NewLine & WebBrowser1.Document.Links(iLink).ToString
Else
TextBox1.Text += WebBrowser1.Document.Links(iLink).InnerText.ToString()
End If
End Sub
Private Delegate Sub UpdateTextBoxCallback(ByVal iLink As Integer)
Private Sub UpdateTextBoxDelegate(ByVal iLink As Integer)
Try
If Me.InvokeRequired Then
Dim cb As New UpdateTextBoxCallback(AddressOf UpdateTextBox)
Me.Invoke(cb, New Object() {iLink})
Else
UpdateTextBox(iLink)
End If
Catch ex As Exception
MessageBox.Show("There was an error " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate("http://stackoverflow.com/")
End Sub

Related

Read weight from a weighing scale and update the UI

I'm facing a big problem here, I'm developing a app to read data from a Weight.
Everything is working perfectly, but the result is not what I expected: when reading the data from the scale, it keeps printing the data without stopping and I would like it to read a single line and whenever there is any change in the scale, just change the value and not add a new line...
The way it's printed:
My code:
Public Class Form1
Dim Q As Queue(Of String) = New Queue(Of String)
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
For Each s In System.IO.Ports.SerialPort.GetPortNames()
ComboBox1.Items.Add(s)
Next s
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
If ComboBox1.SelectedIndex = -1 Then
MsgBox("Please select a port")
Exit Sub
Else
SerialPort1.BaudRate = 9600
SerialPort1.DataBits = 8
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.StopBits = IO.Ports.StopBits.One
SerialPort1.PortName = ComboBox1.SelectedItem.ToString
SerialPort1.Open()
Timer1.Start()
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
Q.Enqueue(SerialPort1.ReadExisting())
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
SyncLock Q
While Q.Count > 0
TextBox1.Text &= Q.Dequeue
End While
End SyncLock
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SerialPort1.Close()
Timer1.Stop()
End Sub
End Class
Here's a simple example using Control.BeginInvoke() to set a Control's property with some data coming from a secondary Thread.
You can use this method since you have all your code in a Form and you use
a SerialPort Component.
Otherwise, build a class to handle the SerialPort and pass a delegate to its Constructor, capture SynchronizationContext.Current and Post() to the delegate.
Or use an IProgress<T> delegate (Progress(Of String) here) and pass this delegate to the class, then just call its Report() method from the event handler.
Assuming ReadExisting() works for you and the Encoding is set correctly (it appears to be, from the results shown in the OP), you could change the code in the DataReceived handler to:
It's required to check whether the handles of the Controls involved (the Form, mainly) are created before calling Invoke() / BeginInvoke(), otherwise you may (will, at some point) get an exception that may kill the application (the IProgress<T> pattern is preferable).
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim comPort = DirectCast(sender, SerialPort)
UpdateUI(comPort.ReadExisting())
End Sub
' [...]
Private lastWeight As String = String.Empty
Private Sub UpdateUI(weight As String)
If IsHandleCreated Then
BeginInvoke(New Action(
Sub()
If Not lastWeight.Equals(weight) Then
lastWeight = weight
If TextBox1.IsHandleCreated Then TextBox1.Text = lastWeight
End If
End Sub))
End If
End Sub
Make a test with a threaded Timer, setting the Interval to a low value (e.g., 50ms).
You can also try to close the Form without stopping the Timer.
Found the soluction:
Public Class Form5
Delegate Sub SetTextCallback(ByVal data As String)
Private Delegate Sub UpdateLabelDelegate(theText As String)
Private Sub UpdateLabel(theText As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateLabelDelegate(AddressOf UpdateLabel), theText)
Else
TextBox1.Text = theText
End If
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim returnStr As String
returnStr = SerialPort1.ReadExisting
Me.BeginInvoke(Sub()
UpdateLabel(returnStr)
End Sub)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SerialPort1.Open()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SerialPort1.Close()
End Sub
End Class

combobox multiple thread error

I have a problem with my code. I keep getting Multiple thread Error with backgroundworker, because of the combobox item display. Please look at my code below its a very simple code which I am planning to use on big scale, all I want it to do is "If item "1" selected show item "1" in label1. I can only assume that problem exists because Combobox runs in different thread....
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.runworkerasync()
BackgroundWorker1.WorkerReportsProgress = True
Me.Cursor = Cursors.WaitCursor 'Cursor changes to wait
End Sub
Public Structure controlwithtext
Public controlname As Control
Public text As String
Public Sub New(ByVal ctrl As Control, ByVal text As String)
Me.controlname = ctrl
Me.text = text
End Sub
End Structure
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
If comboBox1.SelectedItem = "1" then
BackgroundWorker1.ReportProgress(5, New controlwithtext(Label1, ComboBox1.SelectedItem))
End If
End Sub
Private Sub SetBackgroundWorker_ProgressChanged(ByVal sender As Object,
ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
If TypeOf e.UserState Is controlwithtext Then
Dim cwt As controlwithtext = CType(e.UserState, controlwithtext)
cwt.controlname.Text = cwt.text
End If
End Sub
Here's an example of how to read from and write to controls from the BackgroundWorker thread:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While True
System.Threading.Thread.Sleep(250)
Dim selection As String = Me.Invoke(Function()
If Not IsNothing(ComboBox1.SelectedItem) Then
Return ComboBox1.SelectedItem.ToString
Else
Return String.Empty
End If
End Function).ToString
If selection = "1" Then
Me.Invoke(Sub()
Label1.Text = ComboBox1.SelectedItem.ToString
End Sub)
Else
Me.Invoke(Sub()
Label1.Text = "something else"
End Sub)
End If
End While
End Sub

Webbrowser Threading in VB .net

I am trying to limit the time to open webbrowser in vb.net; The conclusion after lots of search seems the threading! I tried the code below; that includes 2 methods I've tried, but nothing working;
I am trying to open the website in 10 seconds in another thread, if website did not respond, then go to the next website and discard that one; my codes are below:
FIRST TRIAL:
Option Explicit On
Option Strict On
Imports System.Threading
Public Class Form1
Dim WorkerThread As Thread
Dim StopThread As Boolean = True
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(" ************************** This is the MAIN thread ************************** ")
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MessageBox.Show(" ************************** This is the SECOND thread ************************** ")
If StopThread = False Then
StopThread = True
Else
StopThread = False
WorkerThread = New Thread(AddressOf Navigate)
WorkerThread.IsBackground = True
WorkerThread.Start()
End If
End Sub
Sub Navigate()
WebBrowser1.Navigate("http://www.mekdam.com")
While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
Application.DoEvents()
End While
End Sub
End Class
SECOND TRIAL
Option Explicit On
Option Strict On
Imports System.Threading
Public Class Form1
Dim WorkerThread As Thread
Dim StopThread As Boolean = True
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(" ************************** This is the MAIN thread ************************** ")
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MessageBox.Show(" ************************** This is the SECOND thread ************************** ")
If StopThread = False Then
StopThread = True
Else
StopThread = False
WorkerThread = New Thread(AddressOf Navigate)
WorkerThread.IsBackground = True
WorkerThread.Start()
End If
End Sub
Sub Navigate()
WebBrowser1.Navigate("http://www.mekdam.com")
While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
Application.DoEvents()
End While
End Sub
End Class

vb For loop repeat a certain number of times

So I am making a port scanner and have a min and max port, but can't get the port scanner to stop scanning when it reaches the maximum port?
I have tried doing an Exit For when port reaches portmax.
Here is the code:
Public Class Form1
Public Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim counter As Integer
Button2.Enabled = False
'set counter explained before to 0
counter = 0
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
Dim host As String
Dim counter As Integer
Dim portmin As Integer = TextBox3.Text
Dim portmax As Integer = TextBox2.Text
'Set the host and port and counter
counter = counter + 1 'counter is for the timer
host = TextBox1.Text
For port As Integer = portmin To portmax
' Next part creates a socket to try and connect
' on with the given user information.
Dim hostadd As System.Net.IPAddress = _
System.Net.Dns.GetHostEntry(host).AddressList(0)
Dim EPhost As New System.Net.IPEndPoint(hostadd, port)
Dim s As New System.Net.Sockets.Socket( _
System.Net.Sockets.AddressFamily.InterNetwork, _
System.Net.Sockets.SocketType.Stream, _
System.Net.Sockets.ProtocolType.Tcp)
Try
s.Connect(EPhost)
Catch
End Try
If Not s.Connected Then
ListBox1.Items.Add("Port " + port.ToString + " is not open")
Else
ListBox1.Items.Add("Port " + port.ToString + " is open")
ListBox2.Items.Add(port.ToString)
End If
Label3.Text = "Open Ports: " + ListBox2.Items.Count.ToString
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
'stop button
Timer1.Stop()
Timer1.Enabled = False
Button1.Enabled = True
Button2.Enabled = False
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.Items.Add("Scanning: " + TextBox1.Text)
ListBox1.Items.Add("-------------------")
Button2.Enabled = True
Button1.Enabled = False
Timer1.Enabled = True
Timer1.Start()
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs) Handles TextBox2.TextChanged
End Sub
Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
End Sub
End Class
I would really appreciate any help
thanks,
Try to stop the Timer while in the scanning.
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Timer1.Enabled = False
'Your code
Timer1.Enabled = True
End Sub
If thats the problem, and looks like it, you should consider using a Try/Catch block:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Try
Timer1.Enabled = False
'Your code
Catch ex As Exception
'Manage the error
Finally
Timer1.Enabled = True
End Try
End Sub
Try this
For port As Integer = portmin To portmax - 1

How to interact with Listbox from Form2 throught thread from Form1

I tried to add items to Listbox in Form2 but noting can't be added, when I put listbox in same form where is thread it works good...Could someone help to make it work with Form2? Here is code:
Public Class Form1
Dim testthread As Threading.Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Control.CheckForIllegalCrossThreadCalls = False
testthread = New Threading.Thread(AddressOf testira)
testthread.Start()
End Sub
Sub testira()
Form2.ListBox1.Items.Add(TextBox1.Text)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Form2.Show()
End Sub
End Class
Here's an example...
Public Class Form1
Private f2 As New Form2
Private Delegate Sub AddItemDelegate(ByVal item As String)
Private Delegate Function GetTextboxTextDelegate(ByVal TB As TextBox) As String
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim testthread As New Threading.Thread(AddressOf testira)
testthread.Start()
End Sub
Sub testira()
Dim item As String = GetTextboxText(TextBox1)
AddItem(item)
End Sub
Private Function GetTextboxText(ByVal TB As TextBox) As String
If TB.InvokeRequired Then
Return TB.Invoke(New GetTextboxTextDelegate(AddressOf GetTextboxText), New Object() {TB})
Else
Return TB.Text
End If
End Function
Private Sub AddItem(ByVal item As String)
If Me.InvokeRequired Then
Me.Invoke(New AddItemDelegate(AddressOf AddItem), New Object() {item})
Else
If IsNothing(f2) OrElse f2.IsDisposed Then
f2 = New Form2
End If
f2.ListBox1.Items.Add(item)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If IsNothing(f2) OrElse f2.IsDisposed Then
f2 = New Form2
End If
f2.Show()
End Sub
End Class