How do I call a function every x minutes in VB.NET? - vb.net

How do I call a function every x minutes.
I assume I'd have to add a timer to the form?

here is a simple example:
Public Class SampleCallEveryXMinute
Private WithEvents xTimer as new System.Windows.Forms.Timer
Public Sub New(TickValue as integer)
xTimer = new System.Windows.Forms.Timer
xTimer.Interval = TickValue
End Sub
Public Sub StartTimer
xTimer.Start
End Sub
Public Sub StopTimer
xTimer.Stop
End Sub
Private Sub Timer_Tick Handles xTimer.Tick
SampleProcedure
End Sub
Private Sub SampleProcedure
'SomeCodesHERE
End Sub
End Class
USAGE:
Dim xSub as new SampleCallEveryXMinute(60000) ' 1000 ms = 1 sec so 60000 ms = 1 min
xSub.StartTimer

Yes, you could add a timer to the form, and set its interval to x*60000, where x is the number of minutes between calls.
Remember that the timer runs on the UI thread, so don't do anything intensive in the function. Also, if the UI thread is busy, the timer event will not fire until the UI thread finishes whatever event it is currently processing. If your function is going to be CPU-intensive, then consider having the timer start up a background worker
If you require a longer time period between function calls (ie, one thats too big for a timer interval) then you could have a timer function that fires every minute, and increments a counter until the desired amount of time has passed, before going on to call the function.

ALTERNATIVE 1
Here is good guide to use the Timer Control in VB.net.
The advantage is that you don't have to worry about modifying UI objects from non UI thread.
ALTERNATIVE 2
Another alternative is to spawn another thread and do the work and sleep the remaining x minutes.
The advantage here is that if your function doesn't touch UI objects your application will remain responsive to user input while the function is being called

Private Sub Form_Load()
_timer.Enabled = True
End Sub
Private Sub _timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
ListBox1.Items.Add(DateTime.Now.ToLongTimeString() + "," + DateTime.Now.ToLongDateString())
End Sub

Related

How to add programatically timer and other controls with source code VB.net

I want to specify in a text field how many timers I want to add to my form and specify the code that should be into the timer.
For instance: My textbox says "2" and then I click a button and it creates two timers and adds a specific source code for both timers.
I have tried different codes and while they worked, I wasn't able to specify the number of controls on a form to create.
How can I achieve this efficiently?
Thanks
Just to create one timer
Public Class Form1
private _timer as Windows.Forms.Timer
...
Public Sub New()
...
_timer = New Timer(Me)
_timer.Interval = 1000 'Timer will trigger one second after start
AddHandler _timer.tick, AddressOf Timer_tick 'Timer will call this sub when done
End Sub
Sub Button_click(sender as Object, e as EventArgs)
_timer.Start() 'Start the timer
...
End Sub
Private Sub Timer_tick(sender as Object, e as EventArgs)
MessageBox.Show("Timerrr!!")
End Sub
...
End Class
Now if you want to create more than one timer, you can use an array of Timer.
In this case, I used a form conatining a NumericUpDown controll element, a button and a label, plus two labels which only contain text.See this picture
To create the timers, I use the function add_timers(timercount), which looks like this:
Function add_timers(timercount As Integer)
'Using a loop to creat <timercount> timers
For g As Integer = 1 To timercount
'Creating new timer 't'
Dim t As New Timer()
'setting interval of t
t.Interval = 1000
'Enabling timer
t.Enabled = True
'Code which runs when t ticks
AddHandler t.Tick, AddressOf TimerTick
Next
End Function
This function gets called when Button1, the start button gets pressed. It uses NumericUpDown1.Value as the parameter for the function. The function uses a loop to create new timers t, sets their intervals and the code to run when they tick.
Unfourtunately, I didn't find a way to dynamically create code, so every timer performs the same action. Using arrays and loops in a clever way might enable you to use different value for each timer. To create code for the timer use a Sub:
Sub TimerTick(ByVal sender As Object, e As EventArgs)
'Add your code here
Label1.Text += 1
End Sub
The complete code I use is:
Public Class Form1
Function add_timers(timercount As Integer)
'Using a loop to creat <timercount> timers
For g As Integer = 1 To timercount
'Creating new timer 't'
Dim t As New Timer()
'setting interval of t
t.Interval = 1000
'Enabling timer
t.Enabled = True
'Code which runs when t ticks
AddHandler t.Tick, AddressOf TimerTick
Next
End Function
Sub TimerTick(ByVal sender As Object, e As EventArgs)
'Add your code here
Label1.Text += 1
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
add_timers(NumericUpDown1.Value)
End Sub
End Class
Packing the timers into an array is possible, that way you can easily access each timer with its index. Serach for it on the internet, and if you then have no idea of how to do it, tell me in the comments.

VB.NET loop timer, multiple "IF" conditions

Writing the title to try and explain my query I think was harder than the problem I'm actually facing :) - Anyway on to the question.
So I have a 20 second timer but I want two different things to happen on the first and second 10 seconds. Specifically to change the active tab.
So I thought to myself I'll just write an if Statement in the timer tick event that if it = 10 seconds to change to the second tab and when it hits 0 to switch back to the first, then to restart the timer.
Below is my code but nothing happens, I think the problem lies with reading the current remaining time.
Private timeLeft2 As Integer
Private Sub timerCountdown2()
timeLeft2 = 20
End Sub
Private Sub tabTimer_Tick(sender As Object, e As EventArgs) Handles tabTimer.Tick
If timeLeft2 = 10 Then
TabControlVertical1.SelectTab(1)
End If
If timeLeft2 = 0 Then
TabControlVertical1.SelectTab(0)
tabTimer.Stop()
tabTimer.Start()
End If
End Sub
The properties of my timer are enabled = true and Interval = 1000
What am I doing wrong?
You should set the timer to trigger the Tick event every 10 seconds, not every 20 (or 1 as by your edit above).
Every time the Tick event is triggered, you look at the value of a global boolean variable.
If this variable is true you execute the code reserved for the first 10 seconds and invert the value of the boolean. When the timer triggers again, you execute the code for the second case and invert again the value of the boolean
So, somewhere in your code or in the designer set the tabTimer interval to 10 seconds
tabTimer.Interval = 10000
and declare a global boolean variable (In the same forms class probably)
Private tabSwitcher as Boolean = True
Now the Tick event could be written as:
(no need to stop the timer if this process needs to continue)
Private Sub tabTimer_Tick(sender As Object, e As EventArgs) Handles tabTimer.Tick
If tabSwitcher = True Then
TabControlVertical1.SelectTab(1)
else
TabControlVertical1.SelectTab(0)
End If
tabSwitcher = Not tabSwitcher
End Sub
This is what I think you are asking:
do something in 10 timer ticks - timer set to 1000
do something else 10 timer ticks later
repeat
Try this
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Static ct As Integer = 0
ct += 1
If ct = 10 Then
'do 10 stuff here
Debug.WriteLine("10")
ElseIf ct = 20 Then
'do 20 stuff here
Debug.WriteLine("20")
'then reset ct <<<<<<<<<<<<
ct = 0
End If
End Sub
Friend Class timerCtrl : Inherits Timer
Private ReadOnly tickFunc As EventHandler = Nothing
Friend Sub New(ByRef theFunc As EventHandler, ByVal theInterval As Integer, Optional ByVal autoStart As Boolean = True)
tickFunc = theFunc
Interval = theInterval
AddHandler Tick, tickFunc
If (autoStart) Then Start()
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
RemoveHandler Tick, tickFunc
End If
MyBase.Dispose(disposing)
End Sub
End Class
Friend Class TabClass
Private timerStep As Boolean = False
Private timerTabs As timerCtrl = Nothing
Friend Sub New()
timerTabs = New timerCtrl(AddressOf timerTabsTick, 10000)
End Sub
Private Sub timerTabsTick(ByVal sender As Object, ByVal e As EventArgs)
timerStep = Not timerStep
If timerStep Then
' condition 1
Else
' condition 2
End If
End Sub
End Class
a simple timer helper class for abstraction. to kill the timer, not just .Stop it, use timerTabs.Dispose(). eliminates the need to detach the event handler separately.
Seems to me that your timer is never getting to the value you are asking for in the if statements due to the fact that you have set the timer to the value of 20.
Also, I've use visual basics and am not to sure but doens't it need to be timeleft2.value?
Also, by stoping and starting the timer, it isn't actually restarting the timer, when you stop it say on 15 secs, and the restart, the timer restarts from 15 secs.
Try this.
If timeLeft2.Value = 10 Then
TabControlVertical1.SelectTab(1)
else if timeLeft2.Value = 0 Then
TabControlVertical1.SelectTab(0)
tabTimer.Stop()
timeLeft2.value = 0
tabTimer.Start()
End If

Events being raised multiple times

I'm trying to create a class that will create a Relogin after certain time but after the first Relogin it keeps populating. Heres my Code:
Private Shared timer As Timer
Public Shared Event DoSomething As Action(Of Integer)
Private Shared _timesCalled As Integer = 0
Public Shared Sub Start()
AddHandler DoSomething, AddressOf EventHandler
timer = New System.Threading.Timer(AddressOf timer_Task, Nothing, 0, 1000)
End Sub
Public Shared Sub [Stop]()
timer.Dispose()
End Sub
Private Shared Sub timer_Task(State As Object)
_timesCalled += 1
If _timesCalled = 15 Then 'Should Raise event every 15s
RaiseEvent DoSomething(_timesCalled)
End If
End Sub
Private Shared Sub EventHandler(ByVal EventNumber As Integer)
My.Application.Dispatcher.Invoke(New Action(AddressOf OpenLogin))
End Sub
Private Shared Sub OpenLogin() 'This event fires multiple times after the first Event
Dim x As New MainWindow
x.ShowDialog() 'Dialog stops code from continuing.
x = Nothing
_timesCalled = 0
End Sub
Open_Login() fires multiple times after the first or second time. Doesn't seem to cause the same problem when I replace "MainWindow" object with a messagebox. Please Help. Thank you.
Notwithstanding the fact that your issue seems to be solved - using an unsynchronised counter is not a reliable way to have an event fired every predetermined period.
The timer event itself fires from a separate .NET managed thread and subsequently, the _timesCalled variable can be accessed from multiple threads. So it is possible that while you are re-setting _timesCalled=0 from your main thread another thread from the default threadpool is about to overwrite this with _timesCalled=14.
In your specific example it is simpler and more straightforward to reschedule the timer event after you’ve finished handling one. That way you can also account for the time it took you to process the event and the timer inaccuracies and lag.
Public Shared Sub Start()
...
' assuming this runs only once
timer = New System.Threading.Timer(AddressOf timer_Task, Nothing, 15000, Timeout.Infinite)
End Sub
Private Shared Sub timer_Task(State As Object)
RaiseEvent DoSomething(_timesCalled)
End Sub
Private Shared Sub OpenLogin()
Dim x As New MainWindow
x.ShowDialog()
x = Nothing
' Reschedule the timer again here, adjust the 15000 if necessary, maybe prefer timer.ChangeTime(...) instead
End Sub
Figured out it was my coding. Everytime MainWindow would load it would run Start() creating a new instance of Timer. Correct issue. Thanks for viewing

[VB.NET]abort code/task after a time

Can i set time limit for a task or a code? for example if i want to show message boxes for 10 seconds and then stop or change the the message body ?
Yes, check out timers. There are three different kinds of timers:
System.Timers.Timer
System.Threading.Timer
System.Windows.Forms.Timer
Which one will work best for you will depend entirely on your specific situation. Given the limited information you provided, I suspect that the easiest way to do what you need to do is to create your own message-box-like form and place a System.Windows.Forms.Timer component on the form (you can find it in the form designer's tool box). Have the form start the timer in its own Shown event. And then show the form using the ShowDialog method.
You can start a Thread and abort it when you want:
Dim t1 As New Threading.Thread(AddressOf MyMethod)
t1.Start()
Timer1.Start()
Private Sub MyMethod()
' Do what you want
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Timer1.Enabled = False
t1.Abort()
End Sub

Waiting in vb2008 / vb.net

I am a VB6 coder and I'm making the move to VB8 / VB.NET
I know how to wait in VB6, but my problem is that I don't know how to wait in VB8/VB.NET. I have a TextBox called textbox2 that contains the number of seconds I want to wait. I used to use wait 60 in VB6, but of course VB2008 is different.
Can anyone help me to do this?
I know this is an old question, but I thought there were so many conflicting answers and I thought the solution I use is simple and straightforward enough.
Also, I wrote this when I switched from VB6 to .net, for the same reason as OP.
Private Sub Wait(ByVal seconds As Long)
Dim dtEndTime As DateTime = DateTime.Now.AddSeconds(seconds)
While DateTime.Now < dtEndTime
Application.DoEvents()
End While
End Sub
Use this do that your UI does not hang.
For i = 1 to 300
threading.thread.sleep(i * 1000)
application.doevents
next
[edit: I re-read the question and see it was specifically asking about a TextBox named textbox2 so I've updated the answer to reflect that.]
Well, I think one answer would be to use:
System.Threading.Thread.Sleep(Int32.Parse(textbox2.Text) * 1000);
if your text box contains the number of seconds to wait. However if you aren't in a background thread, this will hang your application up for the amount of time you are waiting.
You could also do something like:
Dim StartTime As DateTime
StartTime = DateTime.Now
While (DateTime.Now - StartTime) < TimeSpan.FromSeconds(Int32.Parse(textbox2.Text))
System.Threading.Thread.Sleep(500)
Application.DoEvents()
End While
which would not hang up the UI while you wait. (Also, you could use Convert.Int32(textbox2.Text) to convert the data in the textbox.)
Oh, and in certain cases, another way you can avoid the issues with the UI locking up would be do implement a timer callback instead. (see http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx for some more detail.) To do this, you
do whatever processing you need to do before the pause
create a function that picks up processing where you left off
create a timer that calls your function afterward
Code:
Public Class MyClass
Public MyTimer As System.Timers.Timer
Public Sub OnWaitCompleted(source As Object, e As ElapsedEventArgs)
MyTimer.Stop()
MyTimer = Nothing
DoSecondPartOfProcessing()
End Sub
Public Sub DoFirstPartOfProcessing()
' do what you need to do before the wait
MyTimer = New System.Timers.Timer(Int32.Parse(textbox2.Text))
AddHandler MyTimer.Elapsed, AddressOf OnWaitCompleted
MyTimer.Start()
End Sub
Public Sub DoSecondPartOfProcessing()
' do what you need to do after the wait
End Sub
End Class
try to use a timer
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Dim interval As Integer = 0
If Integer.TryParse(Me.TextBox2.Text, interval) Then
Timer1.Enabled = True
Timer1.Interval = interval
Timer1.Start
End If
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
'your code here
End Sub
In the 'event of the timer ticks then implements the logic to invoke the method Timer.Stop (), but this depends on what you do.
Regards.
Use Thread.Sleep:
Thread.Sleep(60000)
Update, following comment:
To retrieve and convert the value of the text box use:
Dim sleepValue As Integer = Integer.Parse(textbox2.Text)
This will throw an exception if the value cannot be converted.
I don't know why do you want it and and why you don't use threads, but this sleep function act similar wait in vb6:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
MsgBox("begin")
Sleep(2000)
MsgBox("end")
End Sub