How to run a thread every x seconds without using timer control - vb.net

I have to run a certain thread every second refreshes the message field, but without using any time controls. I wonder if there is any alternative to timer control. My be background worker or something of that sort.
This what I have so far. It suppose to run every second but it doesn't
Private Sub main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim myThread As New System.Threading.Thread(AddressOf GetData)
myThread.Start()
Thread.Sleep(1000)
End Sub
And this is function which he is calling to:
Delegate Sub SetTextCallback(ByVal newString As String)
Private Sub SetText(ByVal [text] As String)
If Me.ChatBox.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {[text]})
Else
Me.ChatBox.Text = [text]
End If
End Sub​
Sub GetData()
Try
conn.Open()
Dim Query = "SELECT * fROM messages where Time_Posted > Now()"
Dim cmd As MySqlCommand = New MySqlCommand(Query, conn)
Dim theREader As MySqlDataReader = cmd.ExecuteReader
SetText("")
Dim Temp as String = ""
Do While theREader.Read()
Temp &= theREader.GetString(0) & vbCrLf
Loop
SetText(Temp)
conn.Close()
Catch ex As Exception
MsgBox(ex.Message.ToString())
conn.Close()
End Try
GetData()
End Sub
I wonder if there any way how can I make the thread run repeatedly without using timer?
Thank you in advance for any help and suggestions
THIS IS CORRECTED CODE AFTER THE PROBLEM WAS SOLVED

look at this one then
Imports System.Threading
Public Class Form1
Dim testvalue As Integer
Private Sub main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim myThread As New System.Threading.Thread(AddressOf GetData)
myThread.Start()
Thread.Sleep(1000)
End Sub
Sub GetData()
MsgBox("getdata works")
'get your new data from database here
'threadsleep here if you want
'and call GetData() again
GetData()
End Sub
'
'
'
End Class

now i gotta make non stop proc read without any timer.You can add thread sleep if you want
paste it to new project
Public Class Form1
Dim testvalue As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
testvalue = 1
'now we gotta run our proc first time
Read(testvalue)
End Sub
Private Sub Read(ByVal msg As String)
MsgBox(msg)
testvalue += 1 'you make make threadsleep here if you want
Read(testvalue) 'after first start we did what we ant , and now we are running it again
End Sub
End Class

Related

vb.net System.ArgumentOutOfRangeException When Trying to ping

been trying to follow this guide on how to make picture boxes change colour depending on if the ping has been successful or not. I have some test ip's in a CSV file that the program imports
but I keep getting a exception error. I have 3 picture boxes on the page currently defined from picturebox2 - 4
the code for the whole page is below, any suggestions or fixes would be greatly appreciated
Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Threading
Imports System.IO
Imports System.Timers
Public Class Central
Dim pingTable As DataTable = New DataTable()
Dim ipAddress As List(Of String) = New List(Of String)
Dim pictureBoxList As List(Of PictureBox) = New List(Of PictureBox)
Dim timer As Timers.Timer
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
timer = New Timers.Timer
timer.Interval = 20000
timer.Enabled = True
AddHandler timer.Elapsed, AddressOf OnElapsedTime
End Sub
Private Sub OnElapsedTime(ByVal sender As Object, ByVal e As ElapsedEventArgs)
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub FillPingTable()
pingTable.Columns.Add("ip", GetType(String))
pingTable.Columns.Add("picturebox", GetType(String))
pingTable.Rows.Add()
For i As Integer = 0 To ipAddress.Count - 1
pingTable.Rows.Add(ipAddress(i), pictureBoxList(i))
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Hide()
Scot.Show()
End Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
Hide()
Home.Show()
End Sub
Private Sub central_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Using reader = New StreamReader("A:\IpAddress.csv")
While Not reader.EndOfStream
Dim line = reader.ReadLine
Dim values = line.Split(ChrW(10))
ipAddress.Add(values(0))
End While
For i As Integer = 1 To 2
pictureBoxList.Add(CType(Controls.Find("PictureBox" & i, True)(0), PictureBox))
FillPingTable()
BackgroundWorker1.RunWorkerAsync()
Next
End Using
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Thread.Sleep(500)
Parallel.For(0, ipAddress.Count(), Sub(i, loopState)
Dim ping As New Ping()
Dim pingReply As PingReply = ping.Send(ipAddress(i).ToString())
Me.BeginInvoke(CType(Sub()
pictureBoxList(i).SizeMode = PictureBoxSizeMode.Zoom
pictureBoxList(i).BackColor = If(pingReply.Status = IPStatus.Success, Color.Green, Color.Red)
End Sub, Action))
End Sub)
End Sub
End Class

Combo Box Declaration expected

When I got the value for the combo box from the MySQL database it seems getting error declaration expected in line 4. Can anyone help me? Here I attach my code
Imports MySql.Data.MySqlClient
Public Class Utama
Private Sub LogoutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LogoutToolStripMenuItem.Click
Me.Hide()
Dim utama As New Login
utama.Show()
End Sub
Private Sub KeluarToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles KeluarToolStripMenuItem.Click
Me.Close()
End Sub
Private Sub SupplierToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SupplierToolStripMenuItem.Click
Me.Hide()
Dim supplier As New Supplier
supplier.Show()
End Sub
Private Sub ProdukToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ProdukToolStripMenuItem.Click
Me.Hide()
Dim Produk As New Produk
Produk.Show()
End Sub
Private Sub CetakToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CetakToolStripMenuItem.Click
Me.Hide()
Dim Cetak As New Cetak
Cetak.Show()
End Sub
Dim connection As New MySqlConnection("Server=127.0.0.1;Database=pembelian;Uid=root;Pwd=;")
Dim da As New MySqlDataAdapter("select * from supplier", connection)
Dim dt As DataTable
da.fill(dt)
ComboBox1.Datasource=dt
ComboBox1.DisplayMember = "npwp"
ComboBox1.ValueMember = "npwp"
End Class
You need to put that code inside a method. You can't just put arbitrary code anywhere in a class. The only thing that can be directly in the class is a declaration. The first three lines are declarations, so they're OK. The last four lines are not. That code should be inside a method somewhere. If you want to execute that code when the form loads then it should be in the Load event handler. This is pretty elementary stuff that any beginners tutorial would cover, so maybe you should work your way through such a tutorial.
First, create a method as shown below and check the exception.
Private Sub Utama_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim connection As New MySqlConnection("Server=127.0.0.1;Database=pembelian;Uid=root;Pwd=;")
Dim da As New MySqlDataAdapter("select * from supplier", connection)
Dim dt As new DataTable
da.fill(dt)
ComboBox1.Datasource = dt
ComboBox1.DisplayMember = "npwp"
ComboBox1.ValueMember = "npwp"
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub

Visual Basic - Start process or tasks after a specific delay

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Process.Start("https://google.com/")
'I want to wait here for 20 seconds. Then I want him to open the yandex.
Process.Start("https://yandex.com/")
End Sub
Can you help me how can I do. Thanks for all.
In this example you can see how start a process after a specific delay.
In your case is launch a browser but you can use in other scenarios as a technique delay related.
Take a look on code and improve it based in your necessities.
Event TimerDone()
Private Sub ProcessStartAfterDelay(Optional ByVal url As String = "", Optional interval As Integer = 2000)
Dim tmr As System.Windows.Forms.Timer = New System.Windows.Forms.Timer
AddHandler tmr.Tick, Sub()
tmr.Stop()
tmr.Dispose()
If url.Length > 0 Then
Try
Process.Start(url)
RaiseEvent TimerDone()
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
End If
End Sub
tmr.Interval = interval
tmr.Start()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim index As Integer = 0
Dim delay As Integer = 3000
Dim listOfUrls As List(Of String) = New List(Of String)({"https://google.com/",
"https://yandex.com/",
"https://it.yahoo.com/",
"https://www.wikipedia.org/"})
' First launch need to be here with delay > 0 important!
ProcessStartAfterDelay(listOfUrls(index), 1)
AddHandler Me.TimerDone, Sub()
index += 1
If index < listOfUrls.Count Then
ProcessStartAfterDelay(listOfUrls(index), delay)
Else
RemoveHandler Me.TimerDone, Nothing
End If
End Sub
End Sub

Updating progress bar from threadpool

Im trying to update a progress bar in my main form from a threadpool but everything Iv'e tried so far updates the value of the progress bar but not the physical appearance of it, Tried several different ways and still can't find a solution. Can someone please point me in the right direction to update the progress bar on my form1 by 1 every time a thread has completed.
Imports System.Threading
Public Class Form1
Dim arry As New List(Of String)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
BackgroundWorker1.RunWorkerAsync()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim ii As Integer = 2000
For a As Integer = 0 To ii
arry.Add(a)
Next
ProgressBar1.Maximum = arry.Count
ThreadPool.SetMaxThreads(4, 4)
Dim doneEvents(arry.Count) As ManualResetEvent
Dim r As New Random()
For i As Integer = 0 To arry.Count
doneEvents(i) = New ManualResetEvent(False)
Dim f = New stuff(r.Next(20, 40), doneEvents(i))
ThreadPool.QueueUserWorkItem(AddressOf f.ThreadPoolCallBack, i)
Next
For Each handle As WaitHandle In doneEvents
handle.WaitOne()
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False
End Sub
Private Delegate Sub FillDelegate()
Public Sub Fill()
If ProgressBar1.InvokeRequired Then
ProgressBar1.BeginInvoke(New FillDelegate(AddressOf Fill))
Else
ProgressBar1.Increment(1)
ProgressBar1.Refresh()
End If
End Sub
End Class
Public Class stuff
Private _doneEvent As ManualResetEvent
Private _n As Integer
Public ReadOnly Property N() As Integer
Get
Return _n
End Get
End Property
Sub New(ByVal n As Integer, ByVal doneEvent As ManualResetEvent)
_n = n
_doneEvent = doneEvent
End Sub
Public Sub ThreadPoolCallBack(ByVal threadContext As Object)
Try
Dim threadIndex As Integer = CType(threadContext, Integer)
Console.WriteLine("thread {0} started...", threadIndex)
Form1.Fill()
Console.WriteLine("thread {0} finished...", threadIndex)
Catch ex As Exception
Console.WriteLine("error in threadPoolCallback")
Console.WriteLine(ex.Message)
Finally
_doneEvent.Set()
End Try
End Sub
End Class

Using Background Worker VB.NET

I have to show many transaction on any table. It takes so much long time to process.
I want to use a background process in visual basic 2010, but it always give an error message like this "Cross thread operation detected". I have try so many ways that i found in the internet, but still can't find what the problem is.
Please help me about how to fix this problem.
This is my code :
Private Sub CHK_A_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CHK_A.CheckedChanged
Disabled()
P_Panel.Visible = True
B_Worker.RunWorkerAsync()
End Sub
Private Sub BTN_Search_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_Search.Click
USP_Select_Registration()
End Sub
Private Sub B_Worker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles B_Worker.DoWork
Threading.Thread.Sleep(25)
USP_Select_Registration()
End Sub
Private Sub B_Worker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles B_Worker.RunWorkerCompleted
P_Panel.Visible = False
End Sub
This one is my store procedure
Public Sub USP_Select_Registration()
Dim Con As New SqlConnection(SQLCon)
Try
Con.Open()
Dim Cmd As New SqlCommand("USP_Select_Registration", Con)
Cmd.CommandType = CommandType.StoredProcedure
Cmd.Parameters.Add("#Check", SqlDbType.Bit).Value = CHK_A.EditValue
Cmd.Parameters.Add("#Month", SqlDbType.Int).Value = CBO_Month.SelectedIndex + 1
Cmd.Parameters.Add("#Year", SqlDbType.Int).Value = SPE_Year.EditValue
Cmd.Parameters.Add("#Search", SqlDbType.VarChar, 150).Value = TXT_Search.Text
DS_Registration.Tables("MST_Registration").Clear()
Dim Adt As New SqlDataAdapter(Cmd)
Adt.Fill(DS_Registration.Tables("MST_Registration"))
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "Error")
Finally
Con.Close()
End Try
End Sub
I think you get error because inside of USP_Select_Registration you trying to read values from form control's. Which was created by another thread.
RunWorkComleted executes in the same thread where Backgroundworker was created, thats why code P_Panel.Visible = False will executes normally.
But DoWork executes on the another thread.
And when you tried to access some forms controls to read values
TXT_Search.Text - it raise error
You can pass you searching parameters to BackgroundWorker, but you need to add parameters to USP_Select_Registration function.
For example:
Private Sub USP_Select_Registration(searchText as String)
'Your code here
End Sub
Then where you start BackgroundWorker:
B_Worker.RunWorkerAsync(TXT_Search.Text)
And
Private Sub B_Worker_DoWork(ByVal sender As Object,
ByVal e As DoWorkEventArgs) Handles B_Worker.DoWork
Threading.Thread.Sleep(25)
USP_Select_Registration(e.Argument)
End Sub
In your case you need to pass more then one parameter.
So you can create some structure/class or whatever object where you can keep all needed values. And pass that object to RunWorkerAsync